diff options
author | James Bottomley <jejb@titanic.(none)> | 2005-06-17 19:42:23 -0400 |
---|---|---|
committer | James Bottomley <jejb@titanic.(none)> | 2005-06-17 19:42:23 -0400 |
commit | 3237ee78fc00f786d5f5aec6f9310b0e39069f15 (patch) | |
tree | 4c94e70ab846ffcb8bb5715fb3c8d8473358a323 /drivers/scsi/sym53c8xx_2/sym_glue.c | |
parent | 9ee1c939d1cb936b1f98e8d81aeffab57bae46ab (diff) | |
parent | df0ae2497ddefd72a87f3a3b34ff32455d7d4ae0 (diff) |
merge by hand (fix up qla_os.c merge error)
Diffstat (limited to 'drivers/scsi/sym53c8xx_2/sym_glue.c')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 152 |
1 files changed, 81 insertions, 71 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 5b07c6ec3ecc..d76766c3ce16 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c | |||
@@ -155,10 +155,11 @@ pci_get_base_address(struct pci_dev *pdev, int index, unsigned long *basep) | |||
155 | base = tmp; | 155 | base = tmp; |
156 | if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) { | 156 | if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) { |
157 | pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp); | 157 | pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp); |
158 | if (tmp > 0) | 158 | if (tmp > 0) { |
159 | dev_err(&pdev->dev, | 159 | dev_err(&pdev->dev, |
160 | "BAR %d is 64-bit, disabling\n", index - 1); | 160 | "BAR %d is 64-bit, disabling\n", index - 1); |
161 | base = 0; | 161 | base = 0; |
162 | } | ||
162 | } | 163 | } |
163 | 164 | ||
164 | if ((base & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { | 165 | if ((base & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { |
@@ -389,13 +390,20 @@ static int sym_scatter_no_sglist(struct sym_hcb *np, struct sym_ccb *cp, struct | |||
389 | { | 390 | { |
390 | struct sym_tblmove *data = &cp->phys.data[SYM_CONF_MAX_SG-1]; | 391 | struct sym_tblmove *data = &cp->phys.data[SYM_CONF_MAX_SG-1]; |
391 | int segment; | 392 | int segment; |
393 | unsigned int len = cmd->request_bufflen; | ||
392 | 394 | ||
393 | cp->data_len = cmd->request_bufflen; | 395 | if (len) { |
394 | |||
395 | if (cmd->request_bufflen) { | ||
396 | dma_addr_t baddr = map_scsi_single_data(np, cmd); | 396 | dma_addr_t baddr = map_scsi_single_data(np, cmd); |
397 | if (baddr) { | 397 | if (baddr) { |
398 | sym_build_sge(np, data, baddr, cmd->request_bufflen); | 398 | if (len & 1) { |
399 | struct sym_tcb *tp = &np->target[cp->target]; | ||
400 | if (tp->head.wval & EWS) { | ||
401 | len++; | ||
402 | cp->odd_byte_adjustment++; | ||
403 | } | ||
404 | } | ||
405 | cp->data_len = len; | ||
406 | sym_build_sge(np, data, baddr, len); | ||
399 | segment = 1; | 407 | segment = 1; |
400 | } else { | 408 | } else { |
401 | segment = -2; | 409 | segment = -2; |
@@ -418,6 +426,7 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd | |||
418 | segment = sym_scatter_no_sglist(np, cp, cmd); | 426 | segment = sym_scatter_no_sglist(np, cp, cmd); |
419 | else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) { | 427 | else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) { |
420 | struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; | 428 | struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; |
429 | struct sym_tcb *tp = &np->target[cp->target]; | ||
421 | struct sym_tblmove *data; | 430 | struct sym_tblmove *data; |
422 | 431 | ||
423 | if (use_sg > SYM_CONF_MAX_SG) { | 432 | if (use_sg > SYM_CONF_MAX_SG) { |
@@ -431,6 +440,11 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd | |||
431 | dma_addr_t baddr = sg_dma_address(&scatter[segment]); | 440 | dma_addr_t baddr = sg_dma_address(&scatter[segment]); |
432 | unsigned int len = sg_dma_len(&scatter[segment]); | 441 | unsigned int len = sg_dma_len(&scatter[segment]); |
433 | 442 | ||
443 | if ((len & 1) && (tp->head.wval & EWS)) { | ||
444 | len++; | ||
445 | cp->odd_byte_adjustment++; | ||
446 | } | ||
447 | |||
434 | sym_build_sge(np, &data[segment], baddr, len); | 448 | sym_build_sge(np, &data[segment], baddr, len); |
435 | cp->data_len += len; | 449 | cp->data_len += len; |
436 | } | 450 | } |
@@ -456,10 +470,8 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd) | |||
456 | * Minimal checkings, so that we will not | 470 | * Minimal checkings, so that we will not |
457 | * go outside our tables. | 471 | * go outside our tables. |
458 | */ | 472 | */ |
459 | if (sdev->id == np->myaddr || | 473 | if (sdev->id == np->myaddr) { |
460 | sdev->id >= SYM_CONF_MAX_TARGET || | 474 | sym_xpt_done2(np, cmd, DID_NO_CONNECT); |
461 | sdev->lun >= SYM_CONF_MAX_LUN) { | ||
462 | sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE); | ||
463 | return 0; | 475 | return 0; |
464 | } | 476 | } |
465 | 477 | ||
@@ -469,28 +481,6 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd) | |||
469 | tp = &np->target[sdev->id]; | 481 | tp = &np->target[sdev->id]; |
470 | 482 | ||
471 | /* | 483 | /* |
472 | * Complete the 1st INQUIRY command with error | ||
473 | * condition if the device is flagged NOSCAN | ||
474 | * at BOOT in the NVRAM. This may speed up | ||
475 | * the boot and maintain coherency with BIOS | ||
476 | * device numbering. Clearing the flag allows | ||
477 | * user to rescan skipped devices later. | ||
478 | * We also return error for devices not flagged | ||
479 | * for SCAN LUNS in the NVRAM since some mono-lun | ||
480 | * devices behave badly when asked for some non | ||
481 | * zero LUN. Btw, this is an absolute hack.:-) | ||
482 | */ | ||
483 | if (cmd->cmnd[0] == 0x12 || cmd->cmnd[0] == 0x0) { | ||
484 | if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) || | ||
485 | ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && | ||
486 | sdev->lun != 0)) { | ||
487 | tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED; | ||
488 | sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE); | ||
489 | return 0; | ||
490 | } | ||
491 | } | ||
492 | |||
493 | /* | ||
494 | * Select tagged/untagged. | 484 | * Select tagged/untagged. |
495 | */ | 485 | */ |
496 | lp = sym_lp(tp, sdev->lun); | 486 | lp = sym_lp(tp, sdev->lun); |
@@ -511,23 +501,10 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd) | |||
511 | */ | 501 | */ |
512 | static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) | 502 | static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) |
513 | { | 503 | { |
514 | u32 cmd_ba; | ||
515 | int cmd_len; | ||
516 | |||
517 | /* | ||
518 | * CDB is 16 bytes max. | ||
519 | */ | ||
520 | if (cmd->cmd_len > sizeof(cp->cdb_buf)) { | ||
521 | sym_set_cam_status(cp->cmd, CAM_REQ_INVALID); | ||
522 | return -1; | ||
523 | } | ||
524 | |||
525 | memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len); | 504 | memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len); |
526 | cmd_ba = CCB_BA (cp, cdb_buf[0]); | ||
527 | cmd_len = cmd->cmd_len; | ||
528 | 505 | ||
529 | cp->phys.cmd.addr = cpu_to_scr(cmd_ba); | 506 | cp->phys.cmd.addr = CCB_BA(cp, cdb_buf[0]); |
530 | cp->phys.cmd.size = cpu_to_scr(cmd_len); | 507 | cp->phys.cmd.size = cpu_to_scr(cmd->cmd_len); |
531 | 508 | ||
532 | return 0; | 509 | return 0; |
533 | } | 510 | } |
@@ -554,10 +531,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s | |||
554 | if (dir != DMA_NONE) { | 531 | if (dir != DMA_NONE) { |
555 | cp->segments = sym_scatter(np, cp, cmd); | 532 | cp->segments = sym_scatter(np, cp, cmd); |
556 | if (cp->segments < 0) { | 533 | if (cp->segments < 0) { |
557 | if (cp->segments == -2) | 534 | sym_set_cam_status(cmd, DID_ERROR); |
558 | sym_set_cam_status(cmd, CAM_RESRC_UNAVAIL); | ||
559 | else | ||
560 | sym_set_cam_status(cmd, CAM_REQ_TOO_BIG); | ||
561 | goto out_abort; | 535 | goto out_abort; |
562 | } | 536 | } |
563 | } else { | 537 | } else { |
@@ -855,7 +829,7 @@ prepare: | |||
855 | ep->to_do = to_do; | 829 | ep->to_do = to_do; |
856 | /* Complete the command with locks held as required by the driver */ | 830 | /* Complete the command with locks held as required by the driver */ |
857 | if (to_do == SYM_EH_DO_COMPLETE) | 831 | if (to_do == SYM_EH_DO_COMPLETE) |
858 | sym_xpt_done2(np, cmd, CAM_REQ_ABORTED); | 832 | sym_xpt_done2(np, cmd, DID_ABORT); |
859 | 833 | ||
860 | /* Wait for completion with locks released, as required by kernel */ | 834 | /* Wait for completion with locks released, as required by kernel */ |
861 | if (to_do == SYM_EH_DO_WAIT) { | 835 | if (to_do == SYM_EH_DO_WAIT) { |
@@ -882,22 +856,46 @@ prepare: | |||
882 | */ | 856 | */ |
883 | static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd) | 857 | static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd) |
884 | { | 858 | { |
885 | return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd); | 859 | int rc; |
860 | |||
861 | spin_lock_irq(cmd->device->host->host_lock); | ||
862 | rc = sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd); | ||
863 | spin_unlock_irq(cmd->device->host->host_lock); | ||
864 | |||
865 | return rc; | ||
886 | } | 866 | } |
887 | 867 | ||
888 | static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd) | 868 | static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd) |
889 | { | 869 | { |
890 | return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd); | 870 | int rc; |
871 | |||
872 | spin_lock_irq(cmd->device->host->host_lock); | ||
873 | rc = sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd); | ||
874 | spin_unlock_irq(cmd->device->host->host_lock); | ||
875 | |||
876 | return rc; | ||
891 | } | 877 | } |
892 | 878 | ||
893 | static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd) | 879 | static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd) |
894 | { | 880 | { |
895 | return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd); | 881 | int rc; |
882 | |||
883 | spin_lock_irq(cmd->device->host->host_lock); | ||
884 | rc = sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd); | ||
885 | spin_unlock_irq(cmd->device->host->host_lock); | ||
886 | |||
887 | return rc; | ||
896 | } | 888 | } |
897 | 889 | ||
898 | static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd) | 890 | static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd) |
899 | { | 891 | { |
900 | return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); | 892 | int rc; |
893 | |||
894 | spin_lock_irq(cmd->device->host->host_lock); | ||
895 | rc = sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); | ||
896 | spin_unlock_irq(cmd->device->host->host_lock); | ||
897 | |||
898 | return rc; | ||
901 | } | 899 | } |
902 | 900 | ||
903 | /* | 901 | /* |
@@ -921,7 +919,7 @@ static void sym_tune_dev_queuing(struct sym_tcb *tp, int lun, u_short reqtags) | |||
921 | lp->s.reqtags = reqtags; | 919 | lp->s.reqtags = reqtags; |
922 | 920 | ||
923 | if (reqtags != oldtags) { | 921 | if (reqtags != oldtags) { |
924 | dev_info(&tp->sdev->sdev_target->dev, | 922 | dev_info(&tp->starget->dev, |
925 | "tagged command queuing %s, command queue depth %d.\n", | 923 | "tagged command queuing %s, command queue depth %d.\n", |
926 | lp->s.reqtags ? "enabled" : "disabled", | 924 | lp->s.reqtags ? "enabled" : "disabled", |
927 | lp->started_limit); | 925 | lp->started_limit); |
@@ -981,22 +979,34 @@ static int device_queue_depth(struct sym_hcb *np, int target, int lun) | |||
981 | return DEF_DEPTH; | 979 | return DEF_DEPTH; |
982 | } | 980 | } |
983 | 981 | ||
984 | static int sym53c8xx_slave_alloc(struct scsi_device *device) | 982 | static int sym53c8xx_slave_alloc(struct scsi_device *sdev) |
985 | { | 983 | { |
986 | struct sym_hcb *np = sym_get_hcb(device->host); | 984 | struct sym_hcb *np; |
987 | struct sym_tcb *tp = &np->target[device->id]; | 985 | struct sym_tcb *tp; |
988 | if (!tp->sdev) | ||
989 | tp->sdev = device; | ||
990 | 986 | ||
991 | return 0; | 987 | if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN) |
992 | } | 988 | return -ENXIO; |
993 | 989 | ||
994 | static void sym53c8xx_slave_destroy(struct scsi_device *device) | 990 | np = sym_get_hcb(sdev->host); |
995 | { | 991 | tp = &np->target[sdev->id]; |
996 | struct sym_hcb *np = sym_get_hcb(device->host); | 992 | |
997 | struct sym_tcb *tp = &np->target[device->id]; | 993 | /* |
998 | if (tp->sdev == device) | 994 | * Fail the device init if the device is flagged NOSCAN at BOOT in |
999 | tp->sdev = NULL; | 995 | * the NVRAM. This may speed up boot and maintain coherency with |
996 | * BIOS device numbering. Clearing the flag allows the user to | ||
997 | * rescan skipped devices later. We also return an error for | ||
998 | * devices not flagged for SCAN LUNS in the NVRAM since some single | ||
999 | * lun devices behave badly when asked for a non zero LUN. | ||
1000 | */ | ||
1001 | |||
1002 | if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) || | ||
1003 | ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) { | ||
1004 | tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED; | ||
1005 | return -ENXIO; | ||
1006 | } | ||
1007 | |||
1008 | tp->starget = sdev->sdev_target; | ||
1009 | return 0; | ||
1000 | } | 1010 | } |
1001 | 1011 | ||
1002 | /* | 1012 | /* |
@@ -1897,6 +1907,7 @@ static int sym_detach(struct sym_hcb *np, struct pci_dev *pdev) | |||
1897 | */ | 1907 | */ |
1898 | printk("%s: resetting chip\n", sym_name(np)); | 1908 | printk("%s: resetting chip\n", sym_name(np)); |
1899 | OUTB(np, nc_istat, SRST); | 1909 | OUTB(np, nc_istat, SRST); |
1910 | INB(np, nc_mbox1); | ||
1900 | udelay(10); | 1911 | udelay(10); |
1901 | OUTB(np, nc_istat, 0); | 1912 | OUTB(np, nc_istat, 0); |
1902 | 1913 | ||
@@ -1915,7 +1926,6 @@ static struct scsi_host_template sym2_template = { | |||
1915 | .queuecommand = sym53c8xx_queue_command, | 1926 | .queuecommand = sym53c8xx_queue_command, |
1916 | .slave_alloc = sym53c8xx_slave_alloc, | 1927 | .slave_alloc = sym53c8xx_slave_alloc, |
1917 | .slave_configure = sym53c8xx_slave_configure, | 1928 | .slave_configure = sym53c8xx_slave_configure, |
1918 | .slave_destroy = sym53c8xx_slave_destroy, | ||
1919 | .eh_abort_handler = sym53c8xx_eh_abort_handler, | 1929 | .eh_abort_handler = sym53c8xx_eh_abort_handler, |
1920 | .eh_device_reset_handler = sym53c8xx_eh_device_reset_handler, | 1930 | .eh_device_reset_handler = sym53c8xx_eh_device_reset_handler, |
1921 | .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler, | 1931 | .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler, |