Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b90b378a authored by Mark Salyzyn's avatar Mark Salyzyn Committed by James Bottomley
Browse files

[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: default avatarMark Salyzyn <mark_salyzyn@us.xyratex.com>
Acked-by: default avatarJack Wang <jack_wang@usish.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 860eca2b
Loading
Loading
Loading
Loading
+1 −14
Original line number Diff line number Diff line
@@ -356,21 +356,8 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
	do {
		dev = t->dev;
		pm8001_dev = dev->lldd_dev;
		if (DEV_IS_GONE(pm8001_dev)) {
			if (pm8001_dev) {
				PM8001_IO_DBG(pm8001_ha,
					pm8001_printk("device %d not ready.\n",
					pm8001_dev->device_id));
			} else {
				PM8001_IO_DBG(pm8001_ha,
					pm8001_printk("device %016llx not "
					"ready.\n", SAS_ADDR(dev->sas_addr)));
			}
			rc = SAS_PHY_DOWN;
			goto out_done;
		}
		port = &pm8001_ha->port[sas_find_local_port_id(dev)];
		if (!port->port_attached) {
		if (DEV_IS_GONE(pm8001_dev) || !port->port_attached) {
			if (sas_protocol_ata(t->task_proto)) {
				struct task_status_struct *ts = &t->task_status;
				ts->resp = SAS_TASK_UNDELIVERED;