aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pm8001/pm8001_sas.c
diff options
context:
space:
mode:
authorMark Salyzyn <mark_salyzyn@us.xyratex.com>2011-09-22 11:50:01 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-02 14:03:22 -0400
commitb90b378ad5767c0743113c675b09ac00fa534c33 (patch)
tree12d38dfd09898009472831f5cdd1b0dcf8c9da2e /drivers/scsi/pm8001/pm8001_sas.c
parent860eca2b2bf90c513c1d6d9f889b3e0801e7ac08 (diff)
[SCSI] pm8001: fix DEV_IS_GONE infinite retry
On the pm8001, when a device is in the process of going away (device power off or hot plug), depending on the timing, the driver would return SAS_PHY_DOWN as the return value to the queuecommand DEV_IS_GONE logic. The net result is an near infinite retry (especially if SAS debugging is enabled), the logs will fill with: kernel: mpi_ssp_completion 2119:e21:SSP IO status 0x13 tag 0xcc1c0000 dlen=90 param=0xe kernel: wwn=5000c50034069e86 cdb=12 00 00 00 5a 00 00 00 00 00 00 00 00 00 00 00 kernel: sas: lldd_execute_task returned: 138 kernel: sas: lldd_execute_task returned: 138 kernel: sas: lldd_execute_task returned: 138 kernel: sas: lldd_execute_task returned: 138 kernel: sas: lldd_execute_task returned: 138 kernel: sas: lldd_execute_task returned: 138 kernel: sas: lldd_execute_task returned: 138 . . . This patch changes to leverage the port_attached logic to complete the command with a status of PHY_DOWN so that the disposition can be handled immediately and correctly. Signed-off-by: Mark Salyzyn <mark_salyzyn@us.xyratex.com> Acked-by: Jack Wang <jack_wang@usish.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_sas.c')
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c15
1 files changed, 1 insertions, 14 deletions
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 9068f123eccf..dfda00d43326 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -356,21 +356,8 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
356 do { 356 do {
357 dev = t->dev; 357 dev = t->dev;
358 pm8001_dev = dev->lldd_dev; 358 pm8001_dev = dev->lldd_dev;
359 if (DEV_IS_GONE(pm8001_dev)) {
360 if (pm8001_dev) {
361 PM8001_IO_DBG(pm8001_ha,
362 pm8001_printk("device %d not ready.\n",
363 pm8001_dev->device_id));
364 } else {
365 PM8001_IO_DBG(pm8001_ha,
366 pm8001_printk("device %016llx not "
367 "ready.\n", SAS_ADDR(dev->sas_addr)));
368 }
369 rc = SAS_PHY_DOWN;
370 goto out_done;
371 }
372 port = &pm8001_ha->port[sas_find_local_port_id(dev)]; 359 port = &pm8001_ha->port[sas_find_local_port_id(dev)];
373 if (!port->port_attached) { 360 if (DEV_IS_GONE(pm8001_dev) || !port->port_attached) {
374 if (sas_protocol_ata(t->task_proto)) { 361 if (sas_protocol_ata(t->task_proto)) {
375 struct task_status_struct *ts = &t->task_status; 362 struct task_status_struct *ts = &t->task_status;
376 ts->resp = SAS_TASK_UNDELIVERED; 363 ts->resp = SAS_TASK_UNDELIVERED;