diff options
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r-- | drivers/scsi/stex.c | 90 |
1 files changed, 54 insertions, 36 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index baf516d09d79..adda296b594b 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -32,11 +32,12 @@ | |||
32 | #include <scsi/scsi_cmnd.h> | 32 | #include <scsi/scsi_cmnd.h> |
33 | #include <scsi/scsi_host.h> | 33 | #include <scsi/scsi_host.h> |
34 | #include <scsi/scsi_tcq.h> | 34 | #include <scsi/scsi_tcq.h> |
35 | #include <scsi/scsi_dbg.h> | ||
35 | 36 | ||
36 | #define DRV_NAME "stex" | 37 | #define DRV_NAME "stex" |
37 | #define ST_DRIVER_VERSION "3.1.0.1" | 38 | #define ST_DRIVER_VERSION "3.6.0000.1" |
38 | #define ST_VER_MAJOR 3 | 39 | #define ST_VER_MAJOR 3 |
39 | #define ST_VER_MINOR 1 | 40 | #define ST_VER_MINOR 6 |
40 | #define ST_OEM 0 | 41 | #define ST_OEM 0 |
41 | #define ST_BUILD_VER 1 | 42 | #define ST_BUILD_VER 1 |
42 | 43 | ||
@@ -113,10 +114,6 @@ enum { | |||
113 | SG_CF_64B = 0x40, /* 64 bit item */ | 114 | SG_CF_64B = 0x40, /* 64 bit item */ |
114 | SG_CF_HOST = 0x20, /* sg in host memory */ | 115 | SG_CF_HOST = 0x20, /* sg in host memory */ |
115 | 116 | ||
116 | ST_MAX_ARRAY_SUPPORTED = 16, | ||
117 | ST_MAX_TARGET_NUM = (ST_MAX_ARRAY_SUPPORTED+1), | ||
118 | ST_MAX_LUN_PER_TARGET = 16, | ||
119 | |||
120 | st_shasta = 0, | 117 | st_shasta = 0, |
121 | st_vsc = 1, | 118 | st_vsc = 1, |
122 | st_vsc1 = 2, | 119 | st_vsc1 = 2, |
@@ -561,7 +558,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
561 | u16 tag; | 558 | u16 tag; |
562 | host = cmd->device->host; | 559 | host = cmd->device->host; |
563 | id = cmd->device->id; | 560 | id = cmd->device->id; |
564 | lun = cmd->device->channel; /* firmware lun issue work around */ | 561 | lun = cmd->device->lun; |
565 | hba = (struct st_hba *) &host->hostdata[0]; | 562 | hba = (struct st_hba *) &host->hostdata[0]; |
566 | 563 | ||
567 | switch (cmd->cmnd[0]) { | 564 | switch (cmd->cmnd[0]) { |
@@ -580,8 +577,26 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
580 | stex_invalid_field(cmd, done); | 577 | stex_invalid_field(cmd, done); |
581 | return 0; | 578 | return 0; |
582 | } | 579 | } |
580 | case REPORT_LUNS: | ||
581 | /* | ||
582 | * The shasta firmware does not report actual luns in the | ||
583 | * target, so fail the command to force sequential lun scan. | ||
584 | * Also, the console device does not support this command. | ||
585 | */ | ||
586 | if (hba->cardtype == st_shasta || id == host->max_id - 1) { | ||
587 | stex_invalid_field(cmd, done); | ||
588 | return 0; | ||
589 | } | ||
590 | break; | ||
591 | case TEST_UNIT_READY: | ||
592 | if (id == host->max_id - 1) { | ||
593 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | ||
594 | done(cmd); | ||
595 | return 0; | ||
596 | } | ||
597 | break; | ||
583 | case INQUIRY: | 598 | case INQUIRY: |
584 | if (id != ST_MAX_ARRAY_SUPPORTED) | 599 | if (id != host->max_id - 1) |
585 | break; | 600 | break; |
586 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { | 601 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { |
587 | stex_direct_copy(cmd, console_inq_page, | 602 | stex_direct_copy(cmd, console_inq_page, |
@@ -599,7 +614,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
599 | ver.oem = ST_OEM; | 614 | ver.oem = ST_OEM; |
600 | ver.build = ST_BUILD_VER; | 615 | ver.build = ST_BUILD_VER; |
601 | ver.signature[0] = PASSTHRU_SIGNATURE; | 616 | ver.signature[0] = PASSTHRU_SIGNATURE; |
602 | ver.console_id = ST_MAX_ARRAY_SUPPORTED; | 617 | ver.console_id = host->max_id - 1; |
603 | ver.host_no = hba->host->host_no; | 618 | ver.host_no = hba->host->host_no; |
604 | cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ? | 619 | cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ? |
605 | DID_OK << 16 | COMMAND_COMPLETE << 8 : | 620 | DID_OK << 16 | COMMAND_COMPLETE << 8 : |
@@ -620,13 +635,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
620 | 635 | ||
621 | req = stex_alloc_req(hba); | 636 | req = stex_alloc_req(hba); |
622 | 637 | ||
623 | if (hba->cardtype == st_yosemite) { | 638 | req->lun = lun; |
624 | req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id; | 639 | req->target = id; |
625 | req->target = 0; | ||
626 | } else { | ||
627 | req->lun = lun; | ||
628 | req->target = id; | ||
629 | } | ||
630 | 640 | ||
631 | /* cdb */ | 641 | /* cdb */ |
632 | memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); | 642 | memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); |
@@ -730,18 +740,6 @@ static void stex_ys_commands(struct st_hba *hba, | |||
730 | ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; | 740 | ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; |
731 | else | 741 | else |
732 | ccb->srb_status = SRB_STATUS_SUCCESS; | 742 | ccb->srb_status = SRB_STATUS_SUCCESS; |
733 | } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) { | ||
734 | u8 *report_lun_data = (u8 *)hba->copy_buffer; | ||
735 | |||
736 | count = STEX_EXTRA_SIZE; | ||
737 | stex_internal_copy(ccb->cmd, report_lun_data, | ||
738 | &count, ccb->sg_count, ST_FROM_CMD); | ||
739 | if (report_lun_data[2] || report_lun_data[3]) { | ||
740 | report_lun_data[2] = 0x00; | ||
741 | report_lun_data[3] = 0x08; | ||
742 | stex_internal_copy(ccb->cmd, report_lun_data, | ||
743 | &count, ccb->sg_count, ST_TO_CMD); | ||
744 | } | ||
745 | } | 743 | } |
746 | } | 744 | } |
747 | 745 | ||
@@ -958,6 +956,11 @@ static int stex_abort(struct scsi_cmnd *cmd) | |||
958 | u32 data; | 956 | u32 data; |
959 | int result = SUCCESS; | 957 | int result = SUCCESS; |
960 | unsigned long flags; | 958 | unsigned long flags; |
959 | |||
960 | printk(KERN_INFO DRV_NAME | ||
961 | "(%s): aborting command\n", pci_name(hba->pdev)); | ||
962 | scsi_print_command(cmd); | ||
963 | |||
961 | base = hba->mmio_base; | 964 | base = hba->mmio_base; |
962 | spin_lock_irqsave(host->host_lock, flags); | 965 | spin_lock_irqsave(host->host_lock, flags); |
963 | if (tag < host->can_queue && hba->ccb[tag].cmd == cmd) | 966 | if (tag < host->can_queue && hba->ccb[tag].cmd == cmd) |
@@ -1014,7 +1017,12 @@ static void stex_hard_reset(struct st_hba *hba) | |||
1014 | pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl); | 1017 | pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl); |
1015 | pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET; | 1018 | pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET; |
1016 | pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); | 1019 | pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); |
1017 | msleep(1); | 1020 | |
1021 | /* | ||
1022 | * 1 ms may be enough for 8-port controllers. But 16-port controllers | ||
1023 | * require more time to finish bus reset. Use 100 ms here for safety | ||
1024 | */ | ||
1025 | msleep(100); | ||
1018 | pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; | 1026 | pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; |
1019 | pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); | 1027 | pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); |
1020 | 1028 | ||
@@ -1038,6 +1046,10 @@ static int stex_reset(struct scsi_cmnd *cmd) | |||
1038 | unsigned long before; | 1046 | unsigned long before; |
1039 | hba = (struct st_hba *) &cmd->device->host->hostdata[0]; | 1047 | hba = (struct st_hba *) &cmd->device->host->hostdata[0]; |
1040 | 1048 | ||
1049 | printk(KERN_INFO DRV_NAME | ||
1050 | "(%s): resetting host\n", pci_name(hba->pdev)); | ||
1051 | scsi_print_command(cmd); | ||
1052 | |||
1041 | hba->mu_status = MU_STATE_RESETTING; | 1053 | hba->mu_status = MU_STATE_RESETTING; |
1042 | 1054 | ||
1043 | if (hba->cardtype == st_shasta) | 1055 | if (hba->cardtype == st_shasta) |
@@ -1157,7 +1169,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1157 | goto out_scsi_host_put; | 1169 | goto out_scsi_host_put; |
1158 | } | 1170 | } |
1159 | 1171 | ||
1160 | hba->mmio_base = ioremap(pci_resource_start(pdev, 0), | 1172 | hba->mmio_base = ioremap_nocache(pci_resource_start(pdev, 0), |
1161 | pci_resource_len(pdev, 0)); | 1173 | pci_resource_len(pdev, 0)); |
1162 | if ( !hba->mmio_base) { | 1174 | if ( !hba->mmio_base) { |
1163 | printk(KERN_ERR DRV_NAME "(%s): memory map failed\n", | 1175 | printk(KERN_ERR DRV_NAME "(%s): memory map failed\n", |
@@ -1192,12 +1204,18 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1192 | hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; | 1204 | hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; |
1193 | hba->mu_status = MU_STATE_STARTING; | 1205 | hba->mu_status = MU_STATE_STARTING; |
1194 | 1206 | ||
1195 | /* firmware uses id/lun pair for a logical drive, but lun would be | 1207 | if (hba->cardtype == st_shasta) { |
1196 | always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use | 1208 | host->max_lun = 8; |
1197 | channel to map lun here */ | 1209 | host->max_id = 16 + 1; |
1198 | host->max_channel = ST_MAX_LUN_PER_TARGET - 1; | 1210 | } else if (hba->cardtype == st_yosemite) { |
1199 | host->max_id = ST_MAX_TARGET_NUM; | 1211 | host->max_lun = 128; |
1200 | host->max_lun = 1; | 1212 | host->max_id = 1 + 1; |
1213 | } else { | ||
1214 | /* st_vsc and st_vsc1 */ | ||
1215 | host->max_lun = 1; | ||
1216 | host->max_id = 128 + 1; | ||
1217 | } | ||
1218 | host->max_channel = 0; | ||
1201 | host->unique_id = host->host_no; | 1219 | host->unique_id = host->host_no; |
1202 | host->max_cmd_len = STEX_CDB_LENGTH; | 1220 | host->max_cmd_len = STEX_CDB_LENGTH; |
1203 | 1221 | ||