diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-06 15:08:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-06 15:08:30 -0400 |
commit | 8addf0c713061aad2fc256181be3ceac221ac215 (patch) | |
tree | ae759900c1b96e86896fd097bf28c1f7fe9546ac | |
parent | 110e4308f89fed7be824abb681d962eacc0bc319 (diff) | |
parent | 77ae174ddb84800611f5339a8bd53d49df6cd740 (diff) |
Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley:
"This is a set of 13 fixes, a MAINTAINERS update and a sparse update.
The fixes are mostly correct value initialisations, avoiding NULL
derefs and some uninitialised pointer avoidance.
All the patches have been incubated in -next for a few days. The
final patch (use the scsi data buffer length to extract transfer size)
has been rebased to add a cc to stable, but only the commit message
has changed"
* tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
[SCSI] use the scsi data buffer length to extract transfer size
virtio-scsi: fix various bad behavior on aborted requests
virtio-scsi: avoid cancelling uninitialized work items
ibmvscsi: Add memory barriers for send / receive
ibmvscsi: Abort init sequence during error recovery
qla2xxx: Fix sparse warning in qla_target.c.
bnx2fc: Improve stats update mechanism
bnx2fc: do not scan uninitialized lists in case of error.
fc: ensure scan_work isn't active when freeing fc_rport
pm8001: Fix potential null pointer dereference and memory leak.
MAINTAINERS: Update LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) maintainers Email IDs
be2iscsi: remove potential junk pointer free
be2iscsi: add an missing goto in error path
scsi_error: set DID_TIME_OUT correctly
scsi_error: fix invalid setting of host byte
-rw-r--r-- | MAINTAINERS | 9 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 4 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 16 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_io.c | 2 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 13 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_init.c | 13 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 17 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.h | 4 | ||||
-rw-r--r-- | drivers/scsi/scsi_error.c | 20 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_fc.c | 1 | ||||
-rw-r--r-- | drivers/scsi/virtio_scsi.c | 26 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 2 |
13 files changed, 86 insertions, 43 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 56b013a1309a..6813d0aa5ecf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5530,10 +5530,11 @@ S: Maintained | |||
5530 | F: arch/arm/mach-lpc32xx/ | 5530 | F: arch/arm/mach-lpc32xx/ |
5531 | 5531 | ||
5532 | LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) | 5532 | LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) |
5533 | M: Nagalakshmi Nandigama <Nagalakshmi.Nandigama@lsi.com> | 5533 | M: Nagalakshmi Nandigama <nagalakshmi.nandigama@avagotech.com> |
5534 | M: Sreekanth Reddy <Sreekanth.Reddy@lsi.com> | 5534 | M: Praveen Krishnamoorthy <praveen.krishnamoorthy@avagotech.com> |
5535 | M: support@lsi.com | 5535 | M: Sreekanth Reddy <sreekanth.reddy@avagotech.com> |
5536 | L: DL-MPTFusionLinux@lsi.com | 5536 | M: Abhijit Mahajan <abhijit.mahajan@avagotech.com> |
5537 | L: MPT-FusionLinux.pdl@avagotech.com | ||
5537 | L: linux-scsi@vger.kernel.org | 5538 | L: linux-scsi@vger.kernel.org |
5538 | W: http://www.lsilogic.com/support | 5539 | W: http://www.lsilogic.com/support |
5539 | S: Supported | 5540 | S: Supported |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 554349029628..56467df3d6de 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -4198,6 +4198,8 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) | |||
4198 | kfree(phba->ep_array); | 4198 | kfree(phba->ep_array); |
4199 | phba->ep_array = NULL; | 4199 | phba->ep_array = NULL; |
4200 | ret = -ENOMEM; | 4200 | ret = -ENOMEM; |
4201 | |||
4202 | goto free_memory; | ||
4201 | } | 4203 | } |
4202 | 4204 | ||
4203 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { | 4205 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 6045aa78986a..07934b0b9ee1 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -1008,10 +1008,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba, | |||
1008 | BE2_IPV6 : BE2_IPV4 ; | 1008 | BE2_IPV6 : BE2_IPV4 ; |
1009 | 1009 | ||
1010 | rc = mgmt_get_if_info(phba, ip_type, &if_info); | 1010 | rc = mgmt_get_if_info(phba, ip_type, &if_info); |
1011 | if (rc) { | 1011 | if (rc) |
1012 | kfree(if_info); | ||
1013 | return rc; | 1012 | return rc; |
1014 | } | ||
1015 | 1013 | ||
1016 | if (boot_proto == ISCSI_BOOTPROTO_DHCP) { | 1014 | if (boot_proto == ISCSI_BOOTPROTO_DHCP) { |
1017 | if (if_info->dhcp_state) { | 1015 | if (if_info->dhcp_state) { |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index f54843023466..785d0d71781e 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |||
@@ -516,23 +516,17 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) | |||
516 | skb_pull(skb, sizeof(struct fcoe_hdr)); | 516 | skb_pull(skb, sizeof(struct fcoe_hdr)); |
517 | fr_len = skb->len - sizeof(struct fcoe_crc_eof); | 517 | fr_len = skb->len - sizeof(struct fcoe_crc_eof); |
518 | 518 | ||
519 | stats = per_cpu_ptr(lport->stats, get_cpu()); | ||
520 | stats->RxFrames++; | ||
521 | stats->RxWords += fr_len / FCOE_WORD_TO_BYTE; | ||
522 | |||
523 | fp = (struct fc_frame *)skb; | 519 | fp = (struct fc_frame *)skb; |
524 | fc_frame_init(fp); | 520 | fc_frame_init(fp); |
525 | fr_dev(fp) = lport; | 521 | fr_dev(fp) = lport; |
526 | fr_sof(fp) = hp->fcoe_sof; | 522 | fr_sof(fp) = hp->fcoe_sof; |
527 | if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) { | 523 | if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) { |
528 | put_cpu(); | ||
529 | kfree_skb(skb); | 524 | kfree_skb(skb); |
530 | return; | 525 | return; |
531 | } | 526 | } |
532 | fr_eof(fp) = crc_eof.fcoe_eof; | 527 | fr_eof(fp) = crc_eof.fcoe_eof; |
533 | fr_crc(fp) = crc_eof.fcoe_crc32; | 528 | fr_crc(fp) = crc_eof.fcoe_crc32; |
534 | if (pskb_trim(skb, fr_len)) { | 529 | if (pskb_trim(skb, fr_len)) { |
535 | put_cpu(); | ||
536 | kfree_skb(skb); | 530 | kfree_skb(skb); |
537 | return; | 531 | return; |
538 | } | 532 | } |
@@ -544,7 +538,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) | |||
544 | port = lport_priv(vn_port); | 538 | port = lport_priv(vn_port); |
545 | if (!ether_addr_equal(port->data_src_addr, dest_mac)) { | 539 | if (!ether_addr_equal(port->data_src_addr, dest_mac)) { |
546 | BNX2FC_HBA_DBG(lport, "fpma mismatch\n"); | 540 | BNX2FC_HBA_DBG(lport, "fpma mismatch\n"); |
547 | put_cpu(); | ||
548 | kfree_skb(skb); | 541 | kfree_skb(skb); |
549 | return; | 542 | return; |
550 | } | 543 | } |
@@ -552,7 +545,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) | |||
552 | if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && | 545 | if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && |
553 | fh->fh_type == FC_TYPE_FCP) { | 546 | fh->fh_type == FC_TYPE_FCP) { |
554 | /* Drop FCP data. We dont this in L2 path */ | 547 | /* Drop FCP data. We dont this in L2 path */ |
555 | put_cpu(); | ||
556 | kfree_skb(skb); | 548 | kfree_skb(skb); |
557 | return; | 549 | return; |
558 | } | 550 | } |
@@ -562,7 +554,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) | |||
562 | case ELS_LOGO: | 554 | case ELS_LOGO: |
563 | if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { | 555 | if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { |
564 | /* drop non-FIP LOGO */ | 556 | /* drop non-FIP LOGO */ |
565 | put_cpu(); | ||
566 | kfree_skb(skb); | 557 | kfree_skb(skb); |
567 | return; | 558 | return; |
568 | } | 559 | } |
@@ -572,22 +563,23 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) | |||
572 | 563 | ||
573 | if (fh->fh_r_ctl == FC_RCTL_BA_ABTS) { | 564 | if (fh->fh_r_ctl == FC_RCTL_BA_ABTS) { |
574 | /* Drop incoming ABTS */ | 565 | /* Drop incoming ABTS */ |
575 | put_cpu(); | ||
576 | kfree_skb(skb); | 566 | kfree_skb(skb); |
577 | return; | 567 | return; |
578 | } | 568 | } |
579 | 569 | ||
570 | stats = per_cpu_ptr(lport->stats, smp_processor_id()); | ||
571 | stats->RxFrames++; | ||
572 | stats->RxWords += fr_len / FCOE_WORD_TO_BYTE; | ||
573 | |||
580 | if (le32_to_cpu(fr_crc(fp)) != | 574 | if (le32_to_cpu(fr_crc(fp)) != |
581 | ~crc32(~0, skb->data, fr_len)) { | 575 | ~crc32(~0, skb->data, fr_len)) { |
582 | if (stats->InvalidCRCCount < 5) | 576 | if (stats->InvalidCRCCount < 5) |
583 | printk(KERN_WARNING PFX "dropping frame with " | 577 | printk(KERN_WARNING PFX "dropping frame with " |
584 | "CRC error\n"); | 578 | "CRC error\n"); |
585 | stats->InvalidCRCCount++; | 579 | stats->InvalidCRCCount++; |
586 | put_cpu(); | ||
587 | kfree_skb(skb); | 580 | kfree_skb(skb); |
588 | return; | 581 | return; |
589 | } | 582 | } |
590 | put_cpu(); | ||
591 | fc_exch_recv(lport, fp); | 583 | fc_exch_recv(lport, fp); |
592 | } | 584 | } |
593 | 585 | ||
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 32a5e0a2a669..7bc47fc7c686 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | |||
@@ -282,6 +282,8 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) | |||
282 | arr_sz, GFP_KERNEL); | 282 | arr_sz, GFP_KERNEL); |
283 | if (!cmgr->free_list_lock) { | 283 | if (!cmgr->free_list_lock) { |
284 | printk(KERN_ERR PFX "failed to alloc free_list_lock\n"); | 284 | printk(KERN_ERR PFX "failed to alloc free_list_lock\n"); |
285 | kfree(cmgr->free_list); | ||
286 | cmgr->free_list = NULL; | ||
285 | goto mem_err; | 287 | goto mem_err; |
286 | } | 288 | } |
287 | 289 | ||
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 2ebfb2bb0f42..7b23f21f22f1 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -185,6 +185,11 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue) | |||
185 | if (crq->valid & 0x80) { | 185 | if (crq->valid & 0x80) { |
186 | if (++queue->cur == queue->size) | 186 | if (++queue->cur == queue->size) |
187 | queue->cur = 0; | 187 | queue->cur = 0; |
188 | |||
189 | /* Ensure the read of the valid bit occurs before reading any | ||
190 | * other bits of the CRQ entry | ||
191 | */ | ||
192 | rmb(); | ||
188 | } else | 193 | } else |
189 | crq = NULL; | 194 | crq = NULL; |
190 | spin_unlock_irqrestore(&queue->lock, flags); | 195 | spin_unlock_irqrestore(&queue->lock, flags); |
@@ -203,6 +208,11 @@ static int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, | |||
203 | { | 208 | { |
204 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 209 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
205 | 210 | ||
211 | /* | ||
212 | * Ensure the command buffer is flushed to memory before handing it | ||
213 | * over to the VIOS to prevent it from fetching any stale data. | ||
214 | */ | ||
215 | mb(); | ||
206 | return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); | 216 | return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); |
207 | } | 217 | } |
208 | 218 | ||
@@ -797,7 +807,8 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code) | |||
797 | evt->hostdata->dev); | 807 | evt->hostdata->dev); |
798 | if (evt->cmnd_done) | 808 | if (evt->cmnd_done) |
799 | evt->cmnd_done(evt->cmnd); | 809 | evt->cmnd_done(evt->cmnd); |
800 | } else if (evt->done) | 810 | } else if (evt->done && evt->crq.format != VIOSRP_MAD_FORMAT && |
811 | evt->iu.srp.login_req.opcode != SRP_LOGIN_REQ) | ||
801 | evt->done(evt); | 812 | evt->done(evt); |
802 | free_event_struct(&evt->hostdata->pool, evt); | 813 | free_event_struct(&evt->hostdata->pool, evt); |
803 | spin_lock_irqsave(hostdata->host->host_lock, flags); | 814 | spin_lock_irqsave(hostdata->host->host_lock, flags); |
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index c4f31b21feb8..e90c89f1d480 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c | |||
@@ -677,7 +677,7 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) | |||
677 | * pm8001_get_phy_settings_info : Read phy setting values. | 677 | * pm8001_get_phy_settings_info : Read phy setting values. |
678 | * @pm8001_ha : our hba. | 678 | * @pm8001_ha : our hba. |
679 | */ | 679 | */ |
680 | void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) | 680 | static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) |
681 | { | 681 | { |
682 | 682 | ||
683 | #ifdef PM8001_READ_VPD | 683 | #ifdef PM8001_READ_VPD |
@@ -691,11 +691,15 @@ void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) | |||
691 | payload.offset = 0; | 691 | payload.offset = 0; |
692 | payload.length = 4096; | 692 | payload.length = 4096; |
693 | payload.func_specific = kzalloc(4096, GFP_KERNEL); | 693 | payload.func_specific = kzalloc(4096, GFP_KERNEL); |
694 | if (!payload.func_specific) | ||
695 | return -ENOMEM; | ||
694 | /* Read phy setting values from flash */ | 696 | /* Read phy setting values from flash */ |
695 | PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); | 697 | PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); |
696 | wait_for_completion(&completion); | 698 | wait_for_completion(&completion); |
697 | pm8001_set_phy_profile(pm8001_ha, sizeof(u8), payload.func_specific); | 699 | pm8001_set_phy_profile(pm8001_ha, sizeof(u8), payload.func_specific); |
700 | kfree(payload.func_specific); | ||
698 | #endif | 701 | #endif |
702 | return 0; | ||
699 | } | 703 | } |
700 | 704 | ||
701 | #ifdef PM8001_USE_MSIX | 705 | #ifdef PM8001_USE_MSIX |
@@ -879,8 +883,11 @@ static int pm8001_pci_probe(struct pci_dev *pdev, | |||
879 | pm8001_init_sas_add(pm8001_ha); | 883 | pm8001_init_sas_add(pm8001_ha); |
880 | /* phy setting support for motherboard controller */ | 884 | /* phy setting support for motherboard controller */ |
881 | if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 && | 885 | if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 && |
882 | pdev->subsystem_vendor != 0) | 886 | pdev->subsystem_vendor != 0) { |
883 | pm8001_get_phy_settings_info(pm8001_ha); | 887 | rc = pm8001_get_phy_settings_info(pm8001_ha); |
888 | if (rc) | ||
889 | goto err_out_shost; | ||
890 | } | ||
884 | pm8001_post_sas_ha_init(shost, chip); | 891 | pm8001_post_sas_ha_init(shost, chip); |
885 | rc = sas_register_ha(SHOST_TO_SAS_HA(shost)); | 892 | rc = sas_register_ha(SHOST_TO_SAS_HA(shost)); |
886 | if (rc) | 893 | if (rc) |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 4b188b0164e9..e632e14180cf 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -1128,7 +1128,7 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha, | |||
1128 | ctio->u.status1.flags = | 1128 | ctio->u.status1.flags = |
1129 | __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | | 1129 | __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | |
1130 | CTIO7_FLAGS_TERMINATE); | 1130 | CTIO7_FLAGS_TERMINATE); |
1131 | ctio->u.status1.ox_id = entry->fcp_hdr_le.ox_id; | 1131 | ctio->u.status1.ox_id = cpu_to_le16(entry->fcp_hdr_le.ox_id); |
1132 | 1132 | ||
1133 | qla2x00_start_iocbs(vha, vha->req); | 1133 | qla2x00_start_iocbs(vha, vha->req); |
1134 | 1134 | ||
@@ -1262,6 +1262,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, | |||
1262 | { | 1262 | { |
1263 | struct atio_from_isp *atio = &mcmd->orig_iocb.atio; | 1263 | struct atio_from_isp *atio = &mcmd->orig_iocb.atio; |
1264 | struct ctio7_to_24xx *ctio; | 1264 | struct ctio7_to_24xx *ctio; |
1265 | uint16_t temp; | ||
1265 | 1266 | ||
1266 | ql_dbg(ql_dbg_tgt, ha, 0xe008, | 1267 | ql_dbg(ql_dbg_tgt, ha, 0xe008, |
1267 | "Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n", | 1268 | "Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n", |
@@ -1292,7 +1293,8 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, | |||
1292 | ctio->u.status1.flags = (atio->u.isp24.attr << 9) | | 1293 | ctio->u.status1.flags = (atio->u.isp24.attr << 9) | |
1293 | __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | | 1294 | __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | |
1294 | CTIO7_FLAGS_SEND_STATUS); | 1295 | CTIO7_FLAGS_SEND_STATUS); |
1295 | ctio->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); | 1296 | temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id); |
1297 | ctio->u.status1.ox_id = cpu_to_le16(temp); | ||
1296 | ctio->u.status1.scsi_status = | 1298 | ctio->u.status1.scsi_status = |
1297 | __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID); | 1299 | __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID); |
1298 | ctio->u.status1.response_len = __constant_cpu_to_le16(8); | 1300 | ctio->u.status1.response_len = __constant_cpu_to_le16(8); |
@@ -1513,6 +1515,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, | |||
1513 | struct ctio7_to_24xx *pkt; | 1515 | struct ctio7_to_24xx *pkt; |
1514 | struct qla_hw_data *ha = vha->hw; | 1516 | struct qla_hw_data *ha = vha->hw; |
1515 | struct atio_from_isp *atio = &prm->cmd->atio; | 1517 | struct atio_from_isp *atio = &prm->cmd->atio; |
1518 | uint16_t temp; | ||
1516 | 1519 | ||
1517 | pkt = (struct ctio7_to_24xx *)vha->req->ring_ptr; | 1520 | pkt = (struct ctio7_to_24xx *)vha->req->ring_ptr; |
1518 | prm->pkt = pkt; | 1521 | prm->pkt = pkt; |
@@ -1541,13 +1544,13 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, | |||
1541 | pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; | 1544 | pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; |
1542 | pkt->exchange_addr = atio->u.isp24.exchange_addr; | 1545 | pkt->exchange_addr = atio->u.isp24.exchange_addr; |
1543 | pkt->u.status0.flags |= (atio->u.isp24.attr << 9); | 1546 | pkt->u.status0.flags |= (atio->u.isp24.attr << 9); |
1544 | pkt->u.status0.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); | 1547 | temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id); |
1548 | pkt->u.status0.ox_id = cpu_to_le16(temp); | ||
1545 | pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset); | 1549 | pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset); |
1546 | 1550 | ||
1547 | ql_dbg(ql_dbg_tgt, vha, 0xe00c, | 1551 | ql_dbg(ql_dbg_tgt, vha, 0xe00c, |
1548 | "qla_target(%d): handle(cmd) -> %08x, timeout %d, ox_id %#x\n", | 1552 | "qla_target(%d): handle(cmd) -> %08x, timeout %d, ox_id %#x\n", |
1549 | vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT, | 1553 | vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT, temp); |
1550 | le16_to_cpu(pkt->u.status0.ox_id)); | ||
1551 | return 0; | 1554 | return 0; |
1552 | } | 1555 | } |
1553 | 1556 | ||
@@ -2619,6 +2622,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha, | |||
2619 | struct qla_hw_data *ha = vha->hw; | 2622 | struct qla_hw_data *ha = vha->hw; |
2620 | request_t *pkt; | 2623 | request_t *pkt; |
2621 | int ret = 0; | 2624 | int ret = 0; |
2625 | uint16_t temp; | ||
2622 | 2626 | ||
2623 | ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha); | 2627 | ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha); |
2624 | 2628 | ||
@@ -2655,7 +2659,8 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha, | |||
2655 | ctio24->u.status1.flags = (atio->u.isp24.attr << 9) | | 2659 | ctio24->u.status1.flags = (atio->u.isp24.attr << 9) | |
2656 | __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | | 2660 | __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | |
2657 | CTIO7_FLAGS_TERMINATE); | 2661 | CTIO7_FLAGS_TERMINATE); |
2658 | ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); | 2662 | temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id); |
2663 | ctio24->u.status1.ox_id = cpu_to_le16(temp); | ||
2659 | 2664 | ||
2660 | /* Most likely, it isn't needed */ | 2665 | /* Most likely, it isn't needed */ |
2661 | ctio24->u.status1.residual = get_unaligned((uint32_t *) | 2666 | ctio24->u.status1.residual = get_unaligned((uint32_t *) |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index e0a58fd13f66..d1d24fb0160a 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -443,7 +443,7 @@ struct ctio7_to_24xx { | |||
443 | uint16_t reserved1; | 443 | uint16_t reserved1; |
444 | __le16 flags; | 444 | __le16 flags; |
445 | uint32_t residual; | 445 | uint32_t residual; |
446 | uint16_t ox_id; | 446 | __le16 ox_id; |
447 | uint16_t scsi_status; | 447 | uint16_t scsi_status; |
448 | uint32_t relative_offset; | 448 | uint32_t relative_offset; |
449 | uint32_t reserved2; | 449 | uint32_t reserved2; |
@@ -458,7 +458,7 @@ struct ctio7_to_24xx { | |||
458 | uint16_t sense_length; | 458 | uint16_t sense_length; |
459 | uint16_t flags; | 459 | uint16_t flags; |
460 | uint32_t residual; | 460 | uint32_t residual; |
461 | uint16_t ox_id; | 461 | __le16 ox_id; |
462 | uint16_t scsi_status; | 462 | uint16_t scsi_status; |
463 | uint16_t response_len; | 463 | uint16_t response_len; |
464 | uint16_t reserved; | 464 | uint16_t reserved; |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index cbe38e5e7955..7e957918f33f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -131,7 +131,7 @@ scmd_eh_abort_handler(struct work_struct *work) | |||
131 | "aborting command %p\n", scmd)); | 131 | "aborting command %p\n", scmd)); |
132 | rtn = scsi_try_to_abort_cmd(sdev->host->hostt, scmd); | 132 | rtn = scsi_try_to_abort_cmd(sdev->host->hostt, scmd); |
133 | if (rtn == SUCCESS) { | 133 | if (rtn == SUCCESS) { |
134 | scmd->result |= DID_TIME_OUT << 16; | 134 | set_host_byte(scmd, DID_TIME_OUT); |
135 | if (scsi_host_eh_past_deadline(sdev->host)) { | 135 | if (scsi_host_eh_past_deadline(sdev->host)) { |
136 | SCSI_LOG_ERROR_RECOVERY(3, | 136 | SCSI_LOG_ERROR_RECOVERY(3, |
137 | scmd_printk(KERN_INFO, scmd, | 137 | scmd_printk(KERN_INFO, scmd, |
@@ -167,7 +167,7 @@ scmd_eh_abort_handler(struct work_struct *work) | |||
167 | scmd_printk(KERN_WARNING, scmd, | 167 | scmd_printk(KERN_WARNING, scmd, |
168 | "scmd %p terminate " | 168 | "scmd %p terminate " |
169 | "aborted command\n", scmd)); | 169 | "aborted command\n", scmd)); |
170 | scmd->result |= DID_TIME_OUT << 16; | 170 | set_host_byte(scmd, DID_TIME_OUT); |
171 | scsi_finish_command(scmd); | 171 | scsi_finish_command(scmd); |
172 | } | 172 | } |
173 | } | 173 | } |
@@ -287,15 +287,15 @@ enum blk_eh_timer_return scsi_times_out(struct request *req) | |||
287 | else if (host->hostt->eh_timed_out) | 287 | else if (host->hostt->eh_timed_out) |
288 | rtn = host->hostt->eh_timed_out(scmd); | 288 | rtn = host->hostt->eh_timed_out(scmd); |
289 | 289 | ||
290 | if (rtn == BLK_EH_NOT_HANDLED && !host->hostt->no_async_abort) | 290 | if (rtn == BLK_EH_NOT_HANDLED) { |
291 | if (scsi_abort_command(scmd) == SUCCESS) | 291 | if (!host->hostt->no_async_abort && |
292 | scsi_abort_command(scmd) == SUCCESS) | ||
292 | return BLK_EH_NOT_HANDLED; | 293 | return BLK_EH_NOT_HANDLED; |
293 | 294 | ||
294 | scmd->result |= DID_TIME_OUT << 16; | 295 | set_host_byte(scmd, DID_TIME_OUT); |
295 | 296 | if (!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)) | |
296 | if (unlikely(rtn == BLK_EH_NOT_HANDLED && | 297 | rtn = BLK_EH_HANDLED; |
297 | !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) | 298 | } |
298 | rtn = BLK_EH_HANDLED; | ||
299 | 299 | ||
300 | return rtn; | 300 | return rtn; |
301 | } | 301 | } |
@@ -1777,7 +1777,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1777 | break; | 1777 | break; |
1778 | case DID_ABORT: | 1778 | case DID_ABORT: |
1779 | if (scmd->eh_eflags & SCSI_EH_ABORT_SCHEDULED) { | 1779 | if (scmd->eh_eflags & SCSI_EH_ABORT_SCHEDULED) { |
1780 | scmd->result |= DID_TIME_OUT << 16; | 1780 | set_host_byte(scmd, DID_TIME_OUT); |
1781 | return SUCCESS; | 1781 | return SUCCESS; |
1782 | } | 1782 | } |
1783 | case DID_NO_CONNECT: | 1783 | case DID_NO_CONNECT: |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index f80908f74ca9..521f5838594b 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -2549,6 +2549,7 @@ fc_rport_final_delete(struct work_struct *work) | |||
2549 | fc_flush_devloss(shost); | 2549 | fc_flush_devloss(shost); |
2550 | if (!cancel_delayed_work(&rport->dev_loss_work)) | 2550 | if (!cancel_delayed_work(&rport->dev_loss_work)) |
2551 | fc_flush_devloss(shost); | 2551 | fc_flush_devloss(shost); |
2552 | cancel_work_sync(&rport->scan_work); | ||
2552 | spin_lock_irqsave(shost->host_lock, flags); | 2553 | spin_lock_irqsave(shost->host_lock, flags); |
2553 | rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; | 2554 | rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; |
2554 | } | 2555 | } |
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 89ee5929eb6d..308256b5e4cb 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
@@ -237,6 +237,16 @@ static void virtscsi_req_done(struct virtqueue *vq) | |||
237 | virtscsi_vq_done(vscsi, req_vq, virtscsi_complete_cmd); | 237 | virtscsi_vq_done(vscsi, req_vq, virtscsi_complete_cmd); |
238 | }; | 238 | }; |
239 | 239 | ||
240 | static void virtscsi_poll_requests(struct virtio_scsi *vscsi) | ||
241 | { | ||
242 | int i, num_vqs; | ||
243 | |||
244 | num_vqs = vscsi->num_queues; | ||
245 | for (i = 0; i < num_vqs; i++) | ||
246 | virtscsi_vq_done(vscsi, &vscsi->req_vqs[i], | ||
247 | virtscsi_complete_cmd); | ||
248 | } | ||
249 | |||
240 | static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf) | 250 | static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf) |
241 | { | 251 | { |
242 | struct virtio_scsi_cmd *cmd = buf; | 252 | struct virtio_scsi_cmd *cmd = buf; |
@@ -253,6 +263,8 @@ static void virtscsi_ctrl_done(struct virtqueue *vq) | |||
253 | virtscsi_vq_done(vscsi, &vscsi->ctrl_vq, virtscsi_complete_free); | 263 | virtscsi_vq_done(vscsi, &vscsi->ctrl_vq, virtscsi_complete_free); |
254 | }; | 264 | }; |
255 | 265 | ||
266 | static void virtscsi_handle_event(struct work_struct *work); | ||
267 | |||
256 | static int virtscsi_kick_event(struct virtio_scsi *vscsi, | 268 | static int virtscsi_kick_event(struct virtio_scsi *vscsi, |
257 | struct virtio_scsi_event_node *event_node) | 269 | struct virtio_scsi_event_node *event_node) |
258 | { | 270 | { |
@@ -260,6 +272,7 @@ static int virtscsi_kick_event(struct virtio_scsi *vscsi, | |||
260 | struct scatterlist sg; | 272 | struct scatterlist sg; |
261 | unsigned long flags; | 273 | unsigned long flags; |
262 | 274 | ||
275 | INIT_WORK(&event_node->work, virtscsi_handle_event); | ||
263 | sg_init_one(&sg, &event_node->event, sizeof(struct virtio_scsi_event)); | 276 | sg_init_one(&sg, &event_node->event, sizeof(struct virtio_scsi_event)); |
264 | 277 | ||
265 | spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); | 278 | spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); |
@@ -377,7 +390,6 @@ static void virtscsi_complete_event(struct virtio_scsi *vscsi, void *buf) | |||
377 | { | 390 | { |
378 | struct virtio_scsi_event_node *event_node = buf; | 391 | struct virtio_scsi_event_node *event_node = buf; |
379 | 392 | ||
380 | INIT_WORK(&event_node->work, virtscsi_handle_event); | ||
381 | schedule_work(&event_node->work); | 393 | schedule_work(&event_node->work); |
382 | } | 394 | } |
383 | 395 | ||
@@ -589,6 +601,18 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) | |||
589 | cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) | 601 | cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) |
590 | ret = SUCCESS; | 602 | ret = SUCCESS; |
591 | 603 | ||
604 | /* | ||
605 | * The spec guarantees that all requests related to the TMF have | ||
606 | * been completed, but the callback might not have run yet if | ||
607 | * we're using independent interrupts (e.g. MSI). Poll the | ||
608 | * virtqueues once. | ||
609 | * | ||
610 | * In the abort case, sc->scsi_done will do nothing, because | ||
611 | * the block layer must have detected a timeout and as a result | ||
612 | * REQ_ATOM_COMPLETE has been set. | ||
613 | */ | ||
614 | virtscsi_poll_requests(vscsi); | ||
615 | |||
592 | out: | 616 | out: |
593 | mempool_free(cmd, virtscsi_cmd_pool); | 617 | mempool_free(cmd, virtscsi_cmd_pool); |
594 | return ret; | 618 | return ret; |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 42ed789ebafc..e0ae71098144 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -318,7 +318,7 @@ static inline void set_driver_byte(struct scsi_cmnd *cmd, char status) | |||
318 | 318 | ||
319 | static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) | 319 | static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) |
320 | { | 320 | { |
321 | unsigned int xfer_len = blk_rq_bytes(scmd->request); | 321 | unsigned int xfer_len = scsi_out(scmd)->length; |
322 | unsigned int prot_op = scsi_get_prot_op(scmd); | 322 | unsigned int prot_op = scsi_get_prot_op(scmd); |
323 | unsigned int sector_size = scmd->device->sector_size; | 323 | unsigned int sector_size = scmd->device->sector_size; |
324 | 324 | ||