diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/Kconfig | 10 | ||||
-rw-r--r-- | drivers/scsi/aic94xx/aic94xx_task.c | 4 | ||||
-rw-r--r-- | drivers/scsi/esp_scsi.c | 3 | ||||
-rw-r--r-- | drivers/scsi/ipr.c | 19 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 65 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 11 | ||||
-rw-r--r-- | drivers/scsi/megaraid.c | 8 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 21 | ||||
-rw-r--r-- | drivers/scsi/scsi_netlink.c | 27 | ||||
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 9 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 84 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_spi.c | 28 |
12 files changed, 153 insertions, 136 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index de6a6418df24..30905cebefbb 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -388,6 +388,7 @@ config SCSI_3W_9XXX | |||
388 | config SCSI_7000FASST | 388 | config SCSI_7000FASST |
389 | tristate "7000FASST SCSI support" | 389 | tristate "7000FASST SCSI support" |
390 | depends on ISA && SCSI && ISA_DMA_API | 390 | depends on ISA && SCSI && ISA_DMA_API |
391 | select CHECK_SIGNATURE | ||
391 | help | 392 | help |
392 | This driver supports the Western Digital 7000 SCSI host adapter | 393 | This driver supports the Western Digital 7000 SCSI host adapter |
393 | family. Some information is in the source: | 394 | family. Some information is in the source: |
@@ -409,6 +410,7 @@ config SCSI_AHA152X | |||
409 | tristate "Adaptec AHA152X/2825 support" | 410 | tristate "Adaptec AHA152X/2825 support" |
410 | depends on ISA && SCSI && !64BIT | 411 | depends on ISA && SCSI && !64BIT |
411 | select SCSI_SPI_ATTRS | 412 | select SCSI_SPI_ATTRS |
413 | select CHECK_SIGNATURE | ||
412 | ---help--- | 414 | ---help--- |
413 | This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825 | 415 | This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825 |
414 | SCSI host adapters. It also works for the AVA-1505, but the IRQ etc. | 416 | SCSI host adapters. It also works for the AVA-1505, but the IRQ etc. |
@@ -616,6 +618,7 @@ config SCSI_DTC3280 | |||
616 | tristate "DTC3180/3280 SCSI support" | 618 | tristate "DTC3180/3280 SCSI support" |
617 | depends on ISA && SCSI | 619 | depends on ISA && SCSI |
618 | select SCSI_SPI_ATTRS | 620 | select SCSI_SPI_ATTRS |
621 | select CHECK_SIGNATURE | ||
619 | help | 622 | help |
620 | This is support for DTC 3180/3280 SCSI Host Adapters. Please read | 623 | This is support for DTC 3180/3280 SCSI Host Adapters. Please read |
621 | the SCSI-HOWTO, available from | 624 | the SCSI-HOWTO, available from |
@@ -690,6 +693,7 @@ config SCSI_EATA_PIO | |||
690 | config SCSI_FUTURE_DOMAIN | 693 | config SCSI_FUTURE_DOMAIN |
691 | tristate "Future Domain 16xx SCSI/AHA-2920A support" | 694 | tristate "Future Domain 16xx SCSI/AHA-2920A support" |
692 | depends on (ISA || PCI) && SCSI | 695 | depends on (ISA || PCI) && SCSI |
696 | select CHECK_SIGNATURE | ||
693 | ---help--- | 697 | ---help--- |
694 | This is support for Future Domain's 16-bit SCSI host adapters | 698 | This is support for Future Domain's 16-bit SCSI host adapters |
695 | (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and | 699 | (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and |
@@ -1358,6 +1362,7 @@ config SCSI_LPFC | |||
1358 | config SCSI_SEAGATE | 1362 | config SCSI_SEAGATE |
1359 | tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" | 1363 | tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" |
1360 | depends on X86 && ISA && SCSI | 1364 | depends on X86 && ISA && SCSI |
1365 | select CHECK_SIGNATURE | ||
1361 | ---help--- | 1366 | ---help--- |
1362 | These are 8-bit SCSI controllers; the ST-01 is also supported by | 1367 | These are 8-bit SCSI controllers; the ST-01 is also supported by |
1363 | this driver. It is explained in section 3.9 of the SCSI-HOWTO, | 1368 | this driver. It is explained in section 3.9 of the SCSI-HOWTO, |
@@ -1431,6 +1436,7 @@ config SCSI_T128 | |||
1431 | tristate "Trantor T128/T128F/T228 SCSI support" | 1436 | tristate "Trantor T128/T128F/T228 SCSI support" |
1432 | depends on ISA && SCSI | 1437 | depends on ISA && SCSI |
1433 | select SCSI_SPI_ATTRS | 1438 | select SCSI_SPI_ATTRS |
1439 | select CHECK_SIGNATURE | ||
1434 | ---help--- | 1440 | ---help--- |
1435 | This is support for a SCSI host adapter. It is explained in section | 1441 | This is support for a SCSI host adapter. It is explained in section |
1436 | 3.11 of the SCSI-HOWTO, available from | 1442 | 3.11 of the SCSI-HOWTO, available from |
@@ -1595,7 +1601,7 @@ config A3000_SCSI | |||
1595 | built-in SCSI controller, say Y. Otherwise, say N. | 1601 | built-in SCSI controller, say Y. Otherwise, say N. |
1596 | 1602 | ||
1597 | To compile this driver as a module, choose M here: the | 1603 | To compile this driver as a module, choose M here: the |
1598 | module will be called wd33c93. | 1604 | module will be called a3000. |
1599 | 1605 | ||
1600 | config A2091_SCSI | 1606 | config A2091_SCSI |
1601 | tristate "A2091/A590 WD33C93A support" | 1607 | tristate "A2091/A590 WD33C93A support" |
@@ -1605,7 +1611,7 @@ config A2091_SCSI | |||
1605 | say N. | 1611 | say N. |
1606 | 1612 | ||
1607 | To compile this driver as a module, choose M here: the | 1613 | To compile this driver as a module, choose M here: the |
1608 | module will be called wd33c93. | 1614 | module will be called a2091. |
1609 | 1615 | ||
1610 | config GVP11_SCSI | 1616 | config GVP11_SCSI |
1611 | tristate "GVP Series II WD33C93A support" | 1617 | tristate "GVP Series II WD33C93A support" |
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 4c759ce3b4a8..f2b23e01401a 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c | |||
@@ -451,7 +451,7 @@ static int asd_build_smp_ascb(struct asd_ascb *ascb, struct sas_task *task, | |||
451 | struct scb *scb; | 451 | struct scb *scb; |
452 | 452 | ||
453 | pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_req, 1, | 453 | pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_req, 1, |
454 | PCI_DMA_FROMDEVICE); | 454 | PCI_DMA_TODEVICE); |
455 | pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_resp, 1, | 455 | pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_resp, 1, |
456 | PCI_DMA_FROMDEVICE); | 456 | PCI_DMA_FROMDEVICE); |
457 | 457 | ||
@@ -486,7 +486,7 @@ static void asd_unbuild_smp_ascb(struct asd_ascb *a) | |||
486 | 486 | ||
487 | BUG_ON(!task); | 487 | BUG_ON(!task); |
488 | pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_req, 1, | 488 | pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_req, 1, |
489 | PCI_DMA_FROMDEVICE); | 489 | PCI_DMA_TODEVICE); |
490 | pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_resp, 1, | 490 | pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_resp, 1, |
491 | PCI_DMA_FROMDEVICE); | 491 | PCI_DMA_FROMDEVICE); |
492 | } | 492 | } |
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index f346fd1953f4..4ed3a5297066 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c | |||
@@ -2314,6 +2314,7 @@ int scsi_esp_register(struct esp *esp, struct device *dev) | |||
2314 | esp->host->transportt = esp_transport_template; | 2314 | esp->host->transportt = esp_transport_template; |
2315 | esp->host->max_lun = ESP_MAX_LUN; | 2315 | esp->host->max_lun = ESP_MAX_LUN; |
2316 | esp->host->cmd_per_lun = 2; | 2316 | esp->host->cmd_per_lun = 2; |
2317 | esp->host->unique_id = instance; | ||
2317 | 2318 | ||
2318 | esp_set_clock_params(esp); | 2319 | esp_set_clock_params(esp); |
2319 | 2320 | ||
@@ -2337,7 +2338,7 @@ int scsi_esp_register(struct esp *esp, struct device *dev) | |||
2337 | if (err) | 2338 | if (err) |
2338 | return err; | 2339 | return err; |
2339 | 2340 | ||
2340 | esp->host->unique_id = instance++; | 2341 | instance++; |
2341 | 2342 | ||
2342 | scsi_scan_host(esp->host); | 2343 | scsi_scan_host(esp->host); |
2343 | 2344 | ||
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index f142eafb6fc7..b41dfb539021 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -3829,18 +3829,18 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, | |||
3829 | 3829 | ||
3830 | /** | 3830 | /** |
3831 | * ipr_sata_reset - Reset the SATA port | 3831 | * ipr_sata_reset - Reset the SATA port |
3832 | * @ap: SATA port to reset | 3832 | * @link: SATA link to reset |
3833 | * @classes: class of the attached device | 3833 | * @classes: class of the attached device |
3834 | * | 3834 | * |
3835 | * This function issues a SATA phy reset to the affected ATA port. | 3835 | * This function issues a SATA phy reset to the affected ATA link. |
3836 | * | 3836 | * |
3837 | * Return value: | 3837 | * Return value: |
3838 | * 0 on success / non-zero on failure | 3838 | * 0 on success / non-zero on failure |
3839 | **/ | 3839 | **/ |
3840 | static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes, | 3840 | static int ipr_sata_reset(struct ata_link *link, unsigned int *classes, |
3841 | unsigned long deadline) | 3841 | unsigned long deadline) |
3842 | { | 3842 | { |
3843 | struct ipr_sata_port *sata_port = ap->private_data; | 3843 | struct ipr_sata_port *sata_port = link->ap->private_data; |
3844 | struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg; | 3844 | struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg; |
3845 | struct ipr_resource_entry *res; | 3845 | struct ipr_resource_entry *res; |
3846 | unsigned long lock_flags = 0; | 3846 | unsigned long lock_flags = 0; |
@@ -4981,22 +4981,22 @@ static void ipr_ata_phy_reset(struct ata_port *ap) | |||
4981 | rc = ipr_device_reset(ioa_cfg, res); | 4981 | rc = ipr_device_reset(ioa_cfg, res); |
4982 | 4982 | ||
4983 | if (rc) { | 4983 | if (rc) { |
4984 | ap->ops->port_disable(ap); | 4984 | ata_port_disable(ap); |
4985 | goto out_unlock; | 4985 | goto out_unlock; |
4986 | } | 4986 | } |
4987 | 4987 | ||
4988 | switch(res->cfgte.proto) { | 4988 | switch(res->cfgte.proto) { |
4989 | case IPR_PROTO_SATA: | 4989 | case IPR_PROTO_SATA: |
4990 | case IPR_PROTO_SAS_STP: | 4990 | case IPR_PROTO_SAS_STP: |
4991 | ap->device[0].class = ATA_DEV_ATA; | 4991 | ap->link.device[0].class = ATA_DEV_ATA; |
4992 | break; | 4992 | break; |
4993 | case IPR_PROTO_SATA_ATAPI: | 4993 | case IPR_PROTO_SATA_ATAPI: |
4994 | case IPR_PROTO_SAS_STP_ATAPI: | 4994 | case IPR_PROTO_SAS_STP_ATAPI: |
4995 | ap->device[0].class = ATA_DEV_ATAPI; | 4995 | ap->link.device[0].class = ATA_DEV_ATAPI; |
4996 | break; | 4996 | break; |
4997 | default: | 4997 | default: |
4998 | ap->device[0].class = ATA_DEV_UNKNOWN; | 4998 | ap->link.device[0].class = ATA_DEV_UNKNOWN; |
4999 | ap->ops->port_disable(ap); | 4999 | ata_port_disable(ap); |
5000 | break; | 5000 | break; |
5001 | }; | 5001 | }; |
5002 | 5002 | ||
@@ -5262,7 +5262,6 @@ static u8 ipr_ata_check_altstatus(struct ata_port *ap) | |||
5262 | } | 5262 | } |
5263 | 5263 | ||
5264 | static struct ata_port_operations ipr_sata_ops = { | 5264 | static struct ata_port_operations ipr_sata_ops = { |
5265 | .port_disable = ata_port_disable, | ||
5266 | .check_status = ipr_ata_check_status, | 5265 | .check_status = ipr_ata_check_status, |
5267 | .check_altstatus = ipr_ata_check_altstatus, | 5266 | .check_altstatus = ipr_ata_check_altstatus, |
5268 | .dev_select = ata_noop_dev_select, | 5267 | .dev_select = ata_noop_dev_select, |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 5606d1e62978..efceed451b46 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -737,12 +737,19 @@ check_mgmt: | |||
737 | */ | 737 | */ |
738 | conn->ctask = list_entry(conn->xmitqueue.next, | 738 | conn->ctask = list_entry(conn->xmitqueue.next, |
739 | struct iscsi_cmd_task, running); | 739 | struct iscsi_cmd_task, running); |
740 | if (conn->ctask->state == ISCSI_TASK_PENDING) { | 740 | switch (conn->ctask->state) { |
741 | case ISCSI_TASK_ABORTING: | ||
742 | break; | ||
743 | case ISCSI_TASK_PENDING: | ||
741 | iscsi_prep_scsi_cmd_pdu(conn->ctask); | 744 | iscsi_prep_scsi_cmd_pdu(conn->ctask); |
742 | conn->session->tt->init_cmd_task(conn->ctask); | 745 | conn->session->tt->init_cmd_task(conn->ctask); |
746 | /* fall through */ | ||
747 | default: | ||
748 | conn->ctask->state = ISCSI_TASK_RUNNING; | ||
749 | break; | ||
743 | } | 750 | } |
744 | conn->ctask->state = ISCSI_TASK_RUNNING; | ||
745 | list_move_tail(conn->xmitqueue.next, &conn->run_list); | 751 | list_move_tail(conn->xmitqueue.next, &conn->run_list); |
752 | |||
746 | rc = iscsi_xmit_ctask(conn); | 753 | rc = iscsi_xmit_ctask(conn); |
747 | if (rc) | 754 | if (rc) |
748 | goto again; | 755 | goto again; |
@@ -1049,7 +1056,9 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, | |||
1049 | ctask->mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, | 1056 | ctask->mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, |
1050 | NULL, 0); | 1057 | NULL, 0); |
1051 | if (!ctask->mtask) { | 1058 | if (!ctask->mtask) { |
1059 | spin_unlock_bh(&session->lock); | ||
1052 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | 1060 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
1061 | spin_lock_bh(&session->lock) | ||
1053 | debug_scsi("abort sent failure [itt 0x%x]\n", ctask->itt); | 1062 | debug_scsi("abort sent failure [itt 0x%x]\n", ctask->itt); |
1054 | return -EPERM; | 1063 | return -EPERM; |
1055 | } | 1064 | } |
@@ -1066,6 +1075,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, | |||
1066 | debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt); | 1075 | debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt); |
1067 | } | 1076 | } |
1068 | spin_unlock_bh(&session->lock); | 1077 | spin_unlock_bh(&session->lock); |
1078 | mutex_unlock(&session->eh_mutex); | ||
1069 | scsi_queue_work(session->host, &conn->xmitwork); | 1079 | scsi_queue_work(session->host, &conn->xmitwork); |
1070 | 1080 | ||
1071 | /* | 1081 | /* |
@@ -1083,6 +1093,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, | |||
1083 | if (signal_pending(current)) | 1093 | if (signal_pending(current)) |
1084 | flush_signals(current); | 1094 | flush_signals(current); |
1085 | del_timer_sync(&conn->tmabort_timer); | 1095 | del_timer_sync(&conn->tmabort_timer); |
1096 | mutex_lock(&session->eh_mutex); | ||
1086 | spin_lock_bh(&session->lock); | 1097 | spin_lock_bh(&session->lock); |
1087 | return 0; | 1098 | return 0; |
1088 | } | 1099 | } |
@@ -1158,31 +1169,45 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
1158 | __iscsi_put_ctask(ctask); | 1169 | __iscsi_put_ctask(ctask); |
1159 | } | 1170 | } |
1160 | 1171 | ||
1172 | static void iscsi_suspend_tx(struct iscsi_conn *conn) | ||
1173 | { | ||
1174 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
1175 | scsi_flush_work(conn->session->host); | ||
1176 | } | ||
1177 | |||
1178 | static void iscsi_start_tx(struct iscsi_conn *conn) | ||
1179 | { | ||
1180 | clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
1181 | scsi_queue_work(conn->session->host, &conn->xmitwork); | ||
1182 | } | ||
1183 | |||
1161 | int iscsi_eh_abort(struct scsi_cmnd *sc) | 1184 | int iscsi_eh_abort(struct scsi_cmnd *sc) |
1162 | { | 1185 | { |
1186 | struct Scsi_Host *host = sc->device->host; | ||
1187 | struct iscsi_session *session = iscsi_hostdata(host->hostdata); | ||
1163 | struct iscsi_cmd_task *ctask; | 1188 | struct iscsi_cmd_task *ctask; |
1164 | struct iscsi_conn *conn; | 1189 | struct iscsi_conn *conn; |
1165 | struct iscsi_session *session; | ||
1166 | int rc; | 1190 | int rc; |
1167 | 1191 | ||
1192 | mutex_lock(&session->eh_mutex); | ||
1193 | spin_lock_bh(&session->lock); | ||
1168 | /* | 1194 | /* |
1169 | * if session was ISCSI_STATE_IN_RECOVERY then we may not have | 1195 | * if session was ISCSI_STATE_IN_RECOVERY then we may not have |
1170 | * got the command. | 1196 | * got the command. |
1171 | */ | 1197 | */ |
1172 | if (!sc->SCp.ptr) { | 1198 | if (!sc->SCp.ptr) { |
1173 | debug_scsi("sc never reached iscsi layer or it completed.\n"); | 1199 | debug_scsi("sc never reached iscsi layer or it completed.\n"); |
1200 | spin_unlock_bh(&session->lock); | ||
1201 | mutex_unlock(&session->eh_mutex); | ||
1174 | return SUCCESS; | 1202 | return SUCCESS; |
1175 | } | 1203 | } |
1176 | 1204 | ||
1177 | ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; | 1205 | ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; |
1178 | conn = ctask->conn; | 1206 | conn = ctask->conn; |
1179 | session = conn->session; | ||
1180 | 1207 | ||
1181 | conn->eh_abort_cnt++; | 1208 | conn->eh_abort_cnt++; |
1182 | debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt); | 1209 | debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt); |
1183 | 1210 | ||
1184 | spin_lock_bh(&session->lock); | ||
1185 | |||
1186 | /* | 1211 | /* |
1187 | * If we are not logged in or we have started a new session | 1212 | * If we are not logged in or we have started a new session |
1188 | * then let the host reset code handle this | 1213 | * then let the host reset code handle this |
@@ -1219,6 +1244,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
1219 | switch (conn->tmabort_state) { | 1244 | switch (conn->tmabort_state) { |
1220 | case TMABORT_SUCCESS: | 1245 | case TMABORT_SUCCESS: |
1221 | spin_unlock_bh(&session->lock); | 1246 | spin_unlock_bh(&session->lock); |
1247 | iscsi_suspend_tx(conn); | ||
1222 | /* | 1248 | /* |
1223 | * clean up task if aborted. grab the recv lock as a writer | 1249 | * clean up task if aborted. grab the recv lock as a writer |
1224 | */ | 1250 | */ |
@@ -1227,11 +1253,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
1227 | fail_command(conn, ctask, DID_ABORT << 16); | 1253 | fail_command(conn, ctask, DID_ABORT << 16); |
1228 | spin_unlock(&session->lock); | 1254 | spin_unlock(&session->lock); |
1229 | write_unlock_bh(conn->recv_lock); | 1255 | write_unlock_bh(conn->recv_lock); |
1230 | /* | 1256 | iscsi_start_tx(conn); |
1231 | * make sure xmit thread is not still touching the | ||
1232 | * ctask/scsi_cmnd | ||
1233 | */ | ||
1234 | scsi_flush_work(session->host); | ||
1235 | goto success_unlocked; | 1257 | goto success_unlocked; |
1236 | case TMABORT_NOT_FOUND: | 1258 | case TMABORT_NOT_FOUND: |
1237 | if (!ctask->sc) { | 1259 | if (!ctask->sc) { |
@@ -1251,12 +1273,14 @@ success: | |||
1251 | spin_unlock_bh(&session->lock); | 1273 | spin_unlock_bh(&session->lock); |
1252 | success_unlocked: | 1274 | success_unlocked: |
1253 | debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); | 1275 | debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); |
1276 | mutex_unlock(&session->eh_mutex); | ||
1254 | return SUCCESS; | 1277 | return SUCCESS; |
1255 | 1278 | ||
1256 | failed: | 1279 | failed: |
1257 | spin_unlock_bh(&session->lock); | 1280 | spin_unlock_bh(&session->lock); |
1258 | failed_unlocked: | 1281 | failed_unlocked: |
1259 | debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); | 1282 | debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); |
1283 | mutex_unlock(&session->eh_mutex); | ||
1260 | return FAILED; | 1284 | return FAILED; |
1261 | } | 1285 | } |
1262 | EXPORT_SYMBOL_GPL(iscsi_eh_abort); | 1286 | EXPORT_SYMBOL_GPL(iscsi_eh_abort); |
@@ -1403,6 +1427,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
1403 | session->max_cmdsn = initial_cmdsn + 1; | 1427 | session->max_cmdsn = initial_cmdsn + 1; |
1404 | session->max_r2t = 1; | 1428 | session->max_r2t = 1; |
1405 | session->tt = iscsit; | 1429 | session->tt = iscsit; |
1430 | mutex_init(&session->eh_mutex); | ||
1406 | 1431 | ||
1407 | /* initialize SCSI PDU commands pool */ | 1432 | /* initialize SCSI PDU commands pool */ |
1408 | if (iscsi_pool_init(&session->cmdpool, session->cmds_max, | 1433 | if (iscsi_pool_init(&session->cmdpool, session->cmds_max, |
@@ -1736,9 +1761,22 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
1736 | { | 1761 | { |
1737 | int old_stop_stage; | 1762 | int old_stop_stage; |
1738 | 1763 | ||
1764 | mutex_lock(&session->eh_mutex); | ||
1739 | spin_lock_bh(&session->lock); | 1765 | spin_lock_bh(&session->lock); |
1740 | if (conn->stop_stage == STOP_CONN_TERM) { | 1766 | if (conn->stop_stage == STOP_CONN_TERM) { |
1741 | spin_unlock_bh(&session->lock); | 1767 | spin_unlock_bh(&session->lock); |
1768 | mutex_unlock(&session->eh_mutex); | ||
1769 | return; | ||
1770 | } | ||
1771 | |||
1772 | /* | ||
1773 | * The LLD either freed/unset the lock on us, or userspace called | ||
1774 | * stop but did not create a proper connection (connection was never | ||
1775 | * bound or it was unbound then stop was called). | ||
1776 | */ | ||
1777 | if (!conn->recv_lock) { | ||
1778 | spin_unlock_bh(&session->lock); | ||
1779 | mutex_unlock(&session->eh_mutex); | ||
1742 | return; | 1780 | return; |
1743 | } | 1781 | } |
1744 | 1782 | ||
@@ -1755,9 +1793,9 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
1755 | old_stop_stage = conn->stop_stage; | 1793 | old_stop_stage = conn->stop_stage; |
1756 | conn->stop_stage = flag; | 1794 | conn->stop_stage = flag; |
1757 | conn->c_stage = ISCSI_CONN_STOPPED; | 1795 | conn->c_stage = ISCSI_CONN_STOPPED; |
1758 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
1759 | spin_unlock_bh(&session->lock); | 1796 | spin_unlock_bh(&session->lock); |
1760 | scsi_flush_work(session->host); | 1797 | |
1798 | iscsi_suspend_tx(conn); | ||
1761 | 1799 | ||
1762 | write_lock_bh(conn->recv_lock); | 1800 | write_lock_bh(conn->recv_lock); |
1763 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); | 1801 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); |
@@ -1786,6 +1824,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
1786 | fail_all_commands(conn); | 1824 | fail_all_commands(conn); |
1787 | flush_control_queues(session, conn); | 1825 | flush_control_queues(session, conn); |
1788 | spin_unlock_bh(&session->lock); | 1826 | spin_unlock_bh(&session->lock); |
1827 | mutex_unlock(&session->eh_mutex); | ||
1789 | } | 1828 | } |
1790 | 1829 | ||
1791 | void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | 1830 | void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 5e573efcf0a7..0829b55c64d2 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -249,17 +249,17 @@ static void sas_ata_phy_reset(struct ata_port *ap) | |||
249 | switch (dev->sata_dev.command_set) { | 249 | switch (dev->sata_dev.command_set) { |
250 | case ATA_COMMAND_SET: | 250 | case ATA_COMMAND_SET: |
251 | SAS_DPRINTK("%s: Found ATA device.\n", __FUNCTION__); | 251 | SAS_DPRINTK("%s: Found ATA device.\n", __FUNCTION__); |
252 | ap->device[0].class = ATA_DEV_ATA; | 252 | ap->link.device[0].class = ATA_DEV_ATA; |
253 | break; | 253 | break; |
254 | case ATAPI_COMMAND_SET: | 254 | case ATAPI_COMMAND_SET: |
255 | SAS_DPRINTK("%s: Found ATAPI device.\n", __FUNCTION__); | 255 | SAS_DPRINTK("%s: Found ATAPI device.\n", __FUNCTION__); |
256 | ap->device[0].class = ATA_DEV_ATAPI; | 256 | ap->link.device[0].class = ATA_DEV_ATAPI; |
257 | break; | 257 | break; |
258 | default: | 258 | default: |
259 | SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", | 259 | SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", |
260 | __FUNCTION__, | 260 | __FUNCTION__, |
261 | dev->sata_dev.command_set); | 261 | dev->sata_dev.command_set); |
262 | ap->device[0].class = ATA_DEV_UNKNOWN; | 262 | ap->link.device[0].class = ATA_DEV_UNKNOWN; |
263 | break; | 263 | break; |
264 | } | 264 | } |
265 | 265 | ||
@@ -317,7 +317,7 @@ static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in, | |||
317 | dev->sata_dev.serror = val; | 317 | dev->sata_dev.serror = val; |
318 | break; | 318 | break; |
319 | case SCR_ACTIVE: | 319 | case SCR_ACTIVE: |
320 | dev->sata_dev.ap->sactive = val; | 320 | dev->sata_dev.ap->link.sactive = val; |
321 | break; | 321 | break; |
322 | default: | 322 | default: |
323 | return -EINVAL; | 323 | return -EINVAL; |
@@ -342,7 +342,7 @@ static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in, | |||
342 | *val = dev->sata_dev.serror; | 342 | *val = dev->sata_dev.serror; |
343 | return 0; | 343 | return 0; |
344 | case SCR_ACTIVE: | 344 | case SCR_ACTIVE: |
345 | *val = dev->sata_dev.ap->sactive; | 345 | *val = dev->sata_dev.ap->link.sactive; |
346 | return 0; | 346 | return 0; |
347 | default: | 347 | default: |
348 | return -EINVAL; | 348 | return -EINVAL; |
@@ -350,7 +350,6 @@ static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in, | |||
350 | } | 350 | } |
351 | 351 | ||
352 | static struct ata_port_operations sas_sata_ops = { | 352 | static struct ata_port_operations sas_sata_ops = { |
353 | .port_disable = ata_port_disable, | ||
354 | .check_status = sas_ata_check_status, | 353 | .check_status = sas_ata_check_status, |
355 | .check_altstatus = sas_ata_check_status, | 354 | .check_altstatus = sas_ata_check_status, |
356 | .dev_select = ata_noop_dev_select, | 355 | .dev_select = ata_noop_dev_select, |
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 9023ec6a0f8e..e7e11f282c8f 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c | |||
@@ -1753,6 +1753,14 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len) | |||
1753 | 1753 | ||
1754 | *len = 0; | 1754 | *len = 0; |
1755 | 1755 | ||
1756 | if (scsi_sg_count(cmd) == 1 && !adapter->has_64bit_addr) { | ||
1757 | sg = scsi_sglist(cmd); | ||
1758 | scb->dma_h_bulkdata = sg_dma_address(sg); | ||
1759 | *buf = (u32)scb->dma_h_bulkdata; | ||
1760 | *len = sg_dma_len(sg); | ||
1761 | return 0; | ||
1762 | } | ||
1763 | |||
1756 | scsi_for_each_sg(cmd, sg, sgcnt, idx) { | 1764 | scsi_for_each_sg(cmd, sg, sgcnt, idx) { |
1757 | if (adapter->has_64bit_addr) { | 1765 | if (adapter->has_64bit_addr) { |
1758 | scb->sgl64[idx].address = sg_dma_address(sg); | 1766 | scb->sgl64[idx].address = sg_dma_address(sg); |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index fac34293bef7..207f1aa08869 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -263,25 +263,12 @@ static int scsi_merge_bio(struct request *rq, struct bio *bio) | |||
263 | bio->bi_rw |= (1 << BIO_RW); | 263 | bio->bi_rw |= (1 << BIO_RW); |
264 | blk_queue_bounce(q, &bio); | 264 | blk_queue_bounce(q, &bio); |
265 | 265 | ||
266 | if (!rq->bio) | 266 | return blk_rq_append_bio(q, rq, bio); |
267 | blk_rq_bio_prep(q, rq, bio); | ||
268 | else if (!ll_back_merge_fn(q, rq, bio)) | ||
269 | return -EINVAL; | ||
270 | else { | ||
271 | rq->biotail->bi_next = bio; | ||
272 | rq->biotail = bio; | ||
273 | } | ||
274 | |||
275 | return 0; | ||
276 | } | 267 | } |
277 | 268 | ||
278 | static int scsi_bi_endio(struct bio *bio, unsigned int bytes_done, int error) | 269 | static void scsi_bi_endio(struct bio *bio, int error) |
279 | { | 270 | { |
280 | if (bio->bi_size) | ||
281 | return 1; | ||
282 | |||
283 | bio_put(bio); | 271 | bio_put(bio); |
284 | return 0; | ||
285 | } | 272 | } |
286 | 273 | ||
287 | /** | 274 | /** |
@@ -342,7 +329,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl, | |||
342 | if (bio->bi_vcnt >= nr_vecs) { | 329 | if (bio->bi_vcnt >= nr_vecs) { |
343 | err = scsi_merge_bio(rq, bio); | 330 | err = scsi_merge_bio(rq, bio); |
344 | if (err) { | 331 | if (err) { |
345 | bio_endio(bio, bio->bi_size, 0); | 332 | bio_endio(bio, 0); |
346 | goto free_bios; | 333 | goto free_bios; |
347 | } | 334 | } |
348 | bio = NULL; | 335 | bio = NULL; |
@@ -365,7 +352,7 @@ free_bios: | |||
365 | /* | 352 | /* |
366 | * call endio instead of bio_put incase it was bounced | 353 | * call endio instead of bio_put incase it was bounced |
367 | */ | 354 | */ |
368 | bio_endio(bio, bio->bi_size, 0); | 355 | bio_endio(bio, 0); |
369 | } | 356 | } |
370 | 357 | ||
371 | return err; | 358 | return err; |
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 4bf9aa547c78..40579edca101 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c | |||
@@ -64,7 +64,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) | |||
64 | 64 | ||
65 | if (nlh->nlmsg_type != SCSI_TRANSPORT_MSG) { | 65 | if (nlh->nlmsg_type != SCSI_TRANSPORT_MSG) { |
66 | err = -EBADMSG; | 66 | err = -EBADMSG; |
67 | goto next_msg; | 67 | return; |
68 | } | 68 | } |
69 | 69 | ||
70 | hdr = NLMSG_DATA(nlh); | 70 | hdr = NLMSG_DATA(nlh); |
@@ -99,27 +99,6 @@ next_msg: | |||
99 | 99 | ||
100 | 100 | ||
101 | /** | 101 | /** |
102 | * scsi_nl_rcv_msg - | ||
103 | * Receive handler for a socket. Extracts a received message buffer from | ||
104 | * the socket, and starts message processing. | ||
105 | * | ||
106 | * @sk: socket | ||
107 | * @len: unused | ||
108 | * | ||
109 | **/ | ||
110 | static void | ||
111 | scsi_nl_rcv(struct sock *sk, int len) | ||
112 | { | ||
113 | struct sk_buff *skb; | ||
114 | |||
115 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { | ||
116 | scsi_nl_rcv_msg(skb); | ||
117 | kfree_skb(skb); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | |||
122 | /** | ||
123 | * scsi_nl_rcv_event - | 102 | * scsi_nl_rcv_event - |
124 | * Event handler for a netlink socket. | 103 | * Event handler for a netlink socket. |
125 | * | 104 | * |
@@ -167,8 +146,8 @@ scsi_netlink_init(void) | |||
167 | return; | 146 | return; |
168 | } | 147 | } |
169 | 148 | ||
170 | scsi_nl_sock = netlink_kernel_create(NETLINK_SCSITRANSPORT, | 149 | scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT, |
171 | SCSI_NL_GRP_CNT, scsi_nl_rcv, NULL, | 150 | SCSI_NL_GRP_CNT, scsi_nl_rcv_msg, NULL, |
172 | THIS_MODULE); | 151 | THIS_MODULE); |
173 | if (!scsi_nl_sock) { | 152 | if (!scsi_nl_sock) { |
174 | printk(KERN_ERR "%s: register of recieve handler failed\n", | 153 | printk(KERN_ERR "%s: register of recieve handler failed\n", |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 8e880ef8b797..daed37df00b1 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -319,16 +319,11 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) | |||
319 | return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; | 319 | return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; |
320 | } | 320 | } |
321 | 321 | ||
322 | static int scsi_bus_uevent(struct device *dev, char **envp, int num_envp, | 322 | static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) |
323 | char *buffer, int buffer_size) | ||
324 | { | 323 | { |
325 | struct scsi_device *sdev = to_scsi_device(dev); | 324 | struct scsi_device *sdev = to_scsi_device(dev); |
326 | int i = 0; | ||
327 | int length = 0; | ||
328 | 325 | ||
329 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | 326 | add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); |
330 | "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); | ||
331 | envp[i] = NULL; | ||
332 | return 0; | 327 | return 0; |
333 | } | 328 | } |
334 | 329 | ||
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 34c1860a259d..5428d15f23c6 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -1097,61 +1097,49 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | /* | 1099 | /* |
1100 | * Get message from skb (based on rtnetlink_rcv_skb). Each message is | 1100 | * Get message from skb. Each message is processed by iscsi_if_recv_msg. |
1101 | * processed by iscsi_if_recv_msg. Malformed skbs with wrong lengths or | 1101 | * Malformed skbs with wrong lengths or invalid creds are not processed. |
1102 | * invalid creds are discarded silently. | ||
1103 | */ | 1102 | */ |
1104 | static void | 1103 | static void |
1105 | iscsi_if_rx(struct sock *sk, int len) | 1104 | iscsi_if_rx(struct sk_buff *skb) |
1106 | { | 1105 | { |
1107 | struct sk_buff *skb; | ||
1108 | |||
1109 | mutex_lock(&rx_queue_mutex); | 1106 | mutex_lock(&rx_queue_mutex); |
1110 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 1107 | while (skb->len >= NLMSG_SPACE(0)) { |
1111 | if (NETLINK_CREDS(skb)->uid) { | 1108 | int err; |
1112 | skb_pull(skb, skb->len); | 1109 | uint32_t rlen; |
1113 | goto free_skb; | 1110 | struct nlmsghdr *nlh; |
1111 | struct iscsi_uevent *ev; | ||
1112 | |||
1113 | nlh = nlmsg_hdr(skb); | ||
1114 | if (nlh->nlmsg_len < sizeof(*nlh) || | ||
1115 | skb->len < nlh->nlmsg_len) { | ||
1116 | break; | ||
1114 | } | 1117 | } |
1115 | 1118 | ||
1116 | while (skb->len >= NLMSG_SPACE(0)) { | 1119 | ev = NLMSG_DATA(nlh); |
1117 | int err; | 1120 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); |
1118 | uint32_t rlen; | 1121 | if (rlen > skb->len) |
1119 | struct nlmsghdr *nlh; | 1122 | rlen = skb->len; |
1120 | struct iscsi_uevent *ev; | ||
1121 | 1123 | ||
1122 | nlh = nlmsg_hdr(skb); | 1124 | err = iscsi_if_recv_msg(skb, nlh); |
1123 | if (nlh->nlmsg_len < sizeof(*nlh) || | 1125 | if (err) { |
1124 | skb->len < nlh->nlmsg_len) { | 1126 | ev->type = ISCSI_KEVENT_IF_ERROR; |
1125 | break; | 1127 | ev->iferror = err; |
1126 | } | ||
1127 | |||
1128 | ev = NLMSG_DATA(nlh); | ||
1129 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | ||
1130 | if (rlen > skb->len) | ||
1131 | rlen = skb->len; | ||
1132 | |||
1133 | err = iscsi_if_recv_msg(skb, nlh); | ||
1134 | if (err) { | ||
1135 | ev->type = ISCSI_KEVENT_IF_ERROR; | ||
1136 | ev->iferror = err; | ||
1137 | } | ||
1138 | do { | ||
1139 | /* | ||
1140 | * special case for GET_STATS: | ||
1141 | * on success - sending reply and stats from | ||
1142 | * inside of if_recv_msg(), | ||
1143 | * on error - fall through. | ||
1144 | */ | ||
1145 | if (ev->type == ISCSI_UEVENT_GET_STATS && !err) | ||
1146 | break; | ||
1147 | err = iscsi_if_send_reply( | ||
1148 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, | ||
1149 | nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); | ||
1150 | } while (err < 0 && err != -ECONNREFUSED); | ||
1151 | skb_pull(skb, rlen); | ||
1152 | } | 1128 | } |
1153 | free_skb: | 1129 | do { |
1154 | kfree_skb(skb); | 1130 | /* |
1131 | * special case for GET_STATS: | ||
1132 | * on success - sending reply and stats from | ||
1133 | * inside of if_recv_msg(), | ||
1134 | * on error - fall through. | ||
1135 | */ | ||
1136 | if (ev->type == ISCSI_UEVENT_GET_STATS && !err) | ||
1137 | break; | ||
1138 | err = iscsi_if_send_reply( | ||
1139 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, | ||
1140 | nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); | ||
1141 | } while (err < 0 && err != -ECONNREFUSED); | ||
1142 | skb_pull(skb, rlen); | ||
1155 | } | 1143 | } |
1156 | mutex_unlock(&rx_queue_mutex); | 1144 | mutex_unlock(&rx_queue_mutex); |
1157 | } | 1145 | } |
@@ -1523,7 +1511,7 @@ static __init int iscsi_transport_init(void) | |||
1523 | if (err) | 1511 | if (err) |
1524 | goto unregister_conn_class; | 1512 | goto unregister_conn_class; |
1525 | 1513 | ||
1526 | nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, NULL, | 1514 | nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, NULL, |
1527 | THIS_MODULE); | 1515 | THIS_MODULE); |
1528 | if (!nls) { | 1516 | if (!nls) { |
1529 | err = -ENOBUFS; | 1517 | err = -ENOBUFS; |
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 6f56f8750635..4df21c92ff1e 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
@@ -787,10 +787,12 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
787 | struct scsi_target *starget = sdev->sdev_target; | 787 | struct scsi_target *starget = sdev->sdev_target; |
788 | struct Scsi_Host *shost = sdev->host; | 788 | struct Scsi_Host *shost = sdev->host; |
789 | int len = sdev->inquiry_len; | 789 | int len = sdev->inquiry_len; |
790 | int min_period = spi_min_period(starget); | ||
791 | int max_width = spi_max_width(starget); | ||
790 | /* first set us up for narrow async */ | 792 | /* first set us up for narrow async */ |
791 | DV_SET(offset, 0); | 793 | DV_SET(offset, 0); |
792 | DV_SET(width, 0); | 794 | DV_SET(width, 0); |
793 | 795 | ||
794 | if (spi_dv_device_compare_inquiry(sdev, buffer, buffer, DV_LOOPS) | 796 | if (spi_dv_device_compare_inquiry(sdev, buffer, buffer, DV_LOOPS) |
795 | != SPI_COMPARE_SUCCESS) { | 797 | != SPI_COMPARE_SUCCESS) { |
796 | starget_printk(KERN_ERR, starget, "Domain Validation Initial Inquiry Failed\n"); | 798 | starget_printk(KERN_ERR, starget, "Domain Validation Initial Inquiry Failed\n"); |
@@ -798,9 +800,13 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
798 | return; | 800 | return; |
799 | } | 801 | } |
800 | 802 | ||
803 | if (!scsi_device_wide(sdev)) { | ||
804 | spi_max_width(starget) = 0; | ||
805 | max_width = 0; | ||
806 | } | ||
807 | |||
801 | /* test width */ | 808 | /* test width */ |
802 | if (i->f->set_width && spi_max_width(starget) && | 809 | if (i->f->set_width && max_width) { |
803 | scsi_device_wide(sdev)) { | ||
804 | i->f->set_width(starget, 1); | 810 | i->f->set_width(starget, 1); |
805 | 811 | ||
806 | if (spi_dv_device_compare_inquiry(sdev, buffer, | 812 | if (spi_dv_device_compare_inquiry(sdev, buffer, |
@@ -809,6 +815,11 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
809 | != SPI_COMPARE_SUCCESS) { | 815 | != SPI_COMPARE_SUCCESS) { |
810 | starget_printk(KERN_ERR, starget, "Wide Transfers Fail\n"); | 816 | starget_printk(KERN_ERR, starget, "Wide Transfers Fail\n"); |
811 | i->f->set_width(starget, 0); | 817 | i->f->set_width(starget, 0); |
818 | /* Make sure we don't force wide back on by asking | ||
819 | * for a transfer period that requires it */ | ||
820 | max_width = 0; | ||
821 | if (min_period < 10) | ||
822 | min_period = 10; | ||
812 | } | 823 | } |
813 | } | 824 | } |
814 | 825 | ||
@@ -828,7 +839,8 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
828 | 839 | ||
829 | /* now set up to the maximum */ | 840 | /* now set up to the maximum */ |
830 | DV_SET(offset, spi_max_offset(starget)); | 841 | DV_SET(offset, spi_max_offset(starget)); |
831 | DV_SET(period, spi_min_period(starget)); | 842 | DV_SET(period, min_period); |
843 | |||
832 | /* try QAS requests; this should be harmless to set if the | 844 | /* try QAS requests; this should be harmless to set if the |
833 | * target supports it */ | 845 | * target supports it */ |
834 | if (scsi_device_qas(sdev)) { | 846 | if (scsi_device_qas(sdev)) { |
@@ -837,14 +849,14 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
837 | DV_SET(qas, 0); | 849 | DV_SET(qas, 0); |
838 | } | 850 | } |
839 | 851 | ||
840 | if (scsi_device_ius(sdev) && spi_min_period(starget) < 9) { | 852 | if (scsi_device_ius(sdev) && min_period < 9) { |
841 | /* This u320 (or u640). Set IU transfers */ | 853 | /* This u320 (or u640). Set IU transfers */ |
842 | DV_SET(iu, 1); | 854 | DV_SET(iu, 1); |
843 | /* Then set the optional parameters */ | 855 | /* Then set the optional parameters */ |
844 | DV_SET(rd_strm, 1); | 856 | DV_SET(rd_strm, 1); |
845 | DV_SET(wr_flow, 1); | 857 | DV_SET(wr_flow, 1); |
846 | DV_SET(rti, 1); | 858 | DV_SET(rti, 1); |
847 | if (spi_min_period(starget) == 8) | 859 | if (min_period == 8) |
848 | DV_SET(pcomp_en, 1); | 860 | DV_SET(pcomp_en, 1); |
849 | } else { | 861 | } else { |
850 | DV_SET(iu, 0); | 862 | DV_SET(iu, 0); |
@@ -862,6 +874,10 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
862 | } else { | 874 | } else { |
863 | DV_SET(dt, 1); | 875 | DV_SET(dt, 1); |
864 | } | 876 | } |
877 | /* set width last because it will pull all the other | ||
878 | * parameters down to required values */ | ||
879 | DV_SET(width, max_width); | ||
880 | |||
865 | /* Do the read only INQUIRY tests */ | 881 | /* Do the read only INQUIRY tests */ |
866 | spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, | 882 | spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, |
867 | spi_dv_device_compare_inquiry); | 883 | spi_dv_device_compare_inquiry); |