aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-01-24 17:52:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-01-24 17:52:30 -0500
commit440e996095586967c39adb623e8428c435d59fa0 (patch)
tree25922c046002d7360af4b1bf3e450a5acea0d068
parentf828d5e2487d57699c1b9143619d03f71b164cda (diff)
parentbcbde52b14b70c6b3d500e8d18c261d7b1c6fed3 (diff)
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
pULL SCSI fixes from James Bottomley: "This consists of four real fixes and three MAINTAINER updates. Three of the fixes are obvious (the DIX and atomic allocation are bug on and warn on fixes and the other is just trivial) and the ipr one is a bit more involved but is required because without it, the card double completes aborted commands and causes a kernel oops" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: MAINTAINERS: ibmvscsi driver maintainer change MAINTAINERS: ibmvfc driver maintainer change MAINTAINERS: Remove self as isci maintainer scsi_debug: test always evaluates to false, || should be used instead scsi: Avoid crashing if device uses DIX but adapter does not support it scsi_debug: use atomic allocation in resp_rsup_opcodes ipr: wait for aborted command responses
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/scsi/ipr.c92
-rw-r--r--drivers/scsi/ipr.h1
-rw-r--r--drivers/scsi/scsi_debug.c4
-rw-r--r--drivers/scsi/scsi_lib.c12
5 files changed, 108 insertions, 6 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 6b7a694bf454..2ebb056cbe0a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4750,14 +4750,14 @@ S: Supported
4750F: drivers/net/ethernet/ibm/ibmveth.* 4750F: drivers/net/ethernet/ibm/ibmveth.*
4751 4751
4752IBM Power Virtual SCSI Device Drivers 4752IBM Power Virtual SCSI Device Drivers
4753M: Nathan Fontenot <nfont@linux.vnet.ibm.com> 4753M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
4754L: linux-scsi@vger.kernel.org 4754L: linux-scsi@vger.kernel.org
4755S: Supported 4755S: Supported
4756F: drivers/scsi/ibmvscsi/ibmvscsi* 4756F: drivers/scsi/ibmvscsi/ibmvscsi*
4757F: drivers/scsi/ibmvscsi/viosrp.h 4757F: drivers/scsi/ibmvscsi/viosrp.h
4758 4758
4759IBM Power Virtual FC Device Drivers 4759IBM Power Virtual FC Device Drivers
4760M: Brian King <brking@linux.vnet.ibm.com> 4760M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
4761L: linux-scsi@vger.kernel.org 4761L: linux-scsi@vger.kernel.org
4762S: Supported 4762S: Supported
4763F: drivers/scsi/ibmvscsi/ibmvfc* 4763F: drivers/scsi/ibmvscsi/ibmvfc*
@@ -4946,7 +4946,6 @@ K: \b(ABS|SYN)_MT_
4946INTEL C600 SERIES SAS CONTROLLER DRIVER 4946INTEL C600 SERIES SAS CONTROLLER DRIVER
4947M: Intel SCU Linux support <intel-linux-scu@intel.com> 4947M: Intel SCU Linux support <intel-linux-scu@intel.com>
4948M: Artur Paszkiewicz <artur.paszkiewicz@intel.com> 4948M: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
4949M: Dave Jiang <dave.jiang@intel.com>
4950L: linux-scsi@vger.kernel.org 4949L: linux-scsi@vger.kernel.org
4951T: git git://git.code.sf.net/p/intel-sas/isci 4950T: git git://git.code.sf.net/p/intel-sas/isci
4952S: Supported 4951S: Supported
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index df4e27cd996a..9219953ee949 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -683,6 +683,7 @@ static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd,
683 ipr_reinit_ipr_cmnd(ipr_cmd); 683 ipr_reinit_ipr_cmnd(ipr_cmd);
684 ipr_cmd->u.scratch = 0; 684 ipr_cmd->u.scratch = 0;
685 ipr_cmd->sibling = NULL; 685 ipr_cmd->sibling = NULL;
686 ipr_cmd->eh_comp = NULL;
686 ipr_cmd->fast_done = fast_done; 687 ipr_cmd->fast_done = fast_done;
687 init_timer(&ipr_cmd->timer); 688 init_timer(&ipr_cmd->timer);
688} 689}
@@ -848,6 +849,8 @@ static void ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd)
848 849
849 scsi_dma_unmap(ipr_cmd->scsi_cmd); 850 scsi_dma_unmap(ipr_cmd->scsi_cmd);
850 scsi_cmd->scsi_done(scsi_cmd); 851 scsi_cmd->scsi_done(scsi_cmd);
852 if (ipr_cmd->eh_comp)
853 complete(ipr_cmd->eh_comp);
851 list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); 854 list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
852} 855}
853 856
@@ -4811,6 +4814,84 @@ static int ipr_slave_alloc(struct scsi_device *sdev)
4811 return rc; 4814 return rc;
4812} 4815}
4813 4816
4817/**
4818 * ipr_match_lun - Match function for specified LUN
4819 * @ipr_cmd: ipr command struct
4820 * @device: device to match (sdev)
4821 *
4822 * Returns:
4823 * 1 if command matches sdev / 0 if command does not match sdev
4824 **/
4825static int ipr_match_lun(struct ipr_cmnd *ipr_cmd, void *device)
4826{
4827 if (ipr_cmd->scsi_cmd && ipr_cmd->scsi_cmd->device == device)
4828 return 1;
4829 return 0;
4830}
4831
4832/**
4833 * ipr_wait_for_ops - Wait for matching commands to complete
4834 * @ipr_cmd: ipr command struct
4835 * @device: device to match (sdev)
4836 * @match: match function to use
4837 *
4838 * Returns:
4839 * SUCCESS / FAILED
4840 **/
4841static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device,
4842 int (*match)(struct ipr_cmnd *, void *))
4843{
4844 struct ipr_cmnd *ipr_cmd;
4845 int wait;
4846 unsigned long flags;
4847 struct ipr_hrr_queue *hrrq;
4848 signed long timeout = IPR_ABORT_TASK_TIMEOUT;
4849 DECLARE_COMPLETION_ONSTACK(comp);
4850
4851 ENTER;
4852 do {
4853 wait = 0;
4854
4855 for_each_hrrq(hrrq, ioa_cfg) {
4856 spin_lock_irqsave(hrrq->lock, flags);
4857 list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) {
4858 if (match(ipr_cmd, device)) {
4859 ipr_cmd->eh_comp = &comp;
4860 wait++;
4861 }
4862 }
4863 spin_unlock_irqrestore(hrrq->lock, flags);
4864 }
4865
4866 if (wait) {
4867 timeout = wait_for_completion_timeout(&comp, timeout);
4868
4869 if (!timeout) {
4870 wait = 0;
4871
4872 for_each_hrrq(hrrq, ioa_cfg) {
4873 spin_lock_irqsave(hrrq->lock, flags);
4874 list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) {
4875 if (match(ipr_cmd, device)) {
4876 ipr_cmd->eh_comp = NULL;
4877 wait++;
4878 }
4879 }
4880 spin_unlock_irqrestore(hrrq->lock, flags);
4881 }
4882
4883 if (wait)
4884 dev_err(&ioa_cfg->pdev->dev, "Timed out waiting for aborted commands\n");
4885 LEAVE;
4886 return wait ? FAILED : SUCCESS;
4887 }
4888 }
4889 } while (wait);
4890
4891 LEAVE;
4892 return SUCCESS;
4893}
4894
4814static int ipr_eh_host_reset(struct scsi_cmnd *cmd) 4895static int ipr_eh_host_reset(struct scsi_cmnd *cmd)
4815{ 4896{
4816 struct ipr_ioa_cfg *ioa_cfg; 4897 struct ipr_ioa_cfg *ioa_cfg;
@@ -5030,11 +5111,17 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
5030static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) 5111static int ipr_eh_dev_reset(struct scsi_cmnd *cmd)
5031{ 5112{
5032 int rc; 5113 int rc;
5114 struct ipr_ioa_cfg *ioa_cfg;
5115
5116 ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata;
5033 5117
5034 spin_lock_irq(cmd->device->host->host_lock); 5118 spin_lock_irq(cmd->device->host->host_lock);
5035 rc = __ipr_eh_dev_reset(cmd); 5119 rc = __ipr_eh_dev_reset(cmd);
5036 spin_unlock_irq(cmd->device->host->host_lock); 5120 spin_unlock_irq(cmd->device->host->host_lock);
5037 5121
5122 if (rc == SUCCESS)
5123 rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun);
5124
5038 return rc; 5125 return rc;
5039} 5126}
5040 5127
@@ -5234,13 +5321,18 @@ static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd)
5234{ 5321{
5235 unsigned long flags; 5322 unsigned long flags;
5236 int rc; 5323 int rc;
5324 struct ipr_ioa_cfg *ioa_cfg;
5237 5325
5238 ENTER; 5326 ENTER;
5239 5327
5328 ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
5329
5240 spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); 5330 spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags);
5241 rc = ipr_cancel_op(scsi_cmd); 5331 rc = ipr_cancel_op(scsi_cmd);
5242 spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); 5332 spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags);
5243 5333
5334 if (rc == SUCCESS)
5335 rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun);
5244 LEAVE; 5336 LEAVE;
5245 return rc; 5337 return rc;
5246} 5338}
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index b4f3eec51bc9..ec03b42fa2b9 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1606,6 +1606,7 @@ struct ipr_cmnd {
1606 struct scsi_device *sdev; 1606 struct scsi_device *sdev;
1607 } u; 1607 } u;
1608 1608
1609 struct completion *eh_comp;
1609 struct ipr_hrr_queue *hrrq; 1610 struct ipr_hrr_queue *hrrq;
1610 struct ipr_ioa_cfg *ioa_cfg; 1611 struct ipr_ioa_cfg *ioa_cfg;
1611}; 1612};
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 7b8b51bc29b4..4aca1b0378c2 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1623,7 +1623,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
1623 req_opcode = cmd[3]; 1623 req_opcode = cmd[3];
1624 req_sa = get_unaligned_be16(cmd + 4); 1624 req_sa = get_unaligned_be16(cmd + 4);
1625 alloc_len = get_unaligned_be32(cmd + 6); 1625 alloc_len = get_unaligned_be32(cmd + 6);
1626 if (alloc_len < 4 && alloc_len > 0xffff) { 1626 if (alloc_len < 4 || alloc_len > 0xffff) {
1627 mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1); 1627 mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1);
1628 return check_condition_result; 1628 return check_condition_result;
1629 } 1629 }
@@ -1631,7 +1631,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
1631 a_len = 8192; 1631 a_len = 8192;
1632 else 1632 else
1633 a_len = alloc_len; 1633 a_len = alloc_len;
1634 arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_KERNEL); 1634 arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_ATOMIC);
1635 if (NULL == arr) { 1635 if (NULL == arr) {
1636 mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, 1636 mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
1637 INSUFF_RES_ASCQ); 1637 INSUFF_RES_ASCQ);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 6d5c0b8cb0bb..17bb541f7cc2 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1143,7 +1143,17 @@ int scsi_init_io(struct scsi_cmnd *cmd)
1143 struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; 1143 struct scsi_data_buffer *prot_sdb = cmd->prot_sdb;
1144 int ivecs, count; 1144 int ivecs, count;
1145 1145
1146 BUG_ON(prot_sdb == NULL); 1146 if (prot_sdb == NULL) {
1147 /*
1148 * This can happen if someone (e.g. multipath)
1149 * queues a command to a device on an adapter
1150 * that does not support DIX.
1151 */
1152 WARN_ON_ONCE(1);
1153 error = BLKPREP_KILL;
1154 goto err_exit;
1155 }
1156
1147 ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio); 1157 ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio);
1148 1158
1149 if (scsi_alloc_sgtable(prot_sdb, ivecs, is_mq)) { 1159 if (scsi_alloc_sgtable(prot_sdb, ivecs, is_mq)) {