提交 eb2a86ae 编写于 作者: O Oliver Neukum 提交者: Greg Kroah-Hartman

USB: UAS: fix disconnect by unplugging a hub

The SCSI layer can go into an ugly loop if you ignore that a device is
gone. You need to report an error in the command rather than in the
return value of the queue method.

We need to specifically check for ENODEV. The issue goes back to the
introduction of the driver.

Fixes: 115bb1ff ("USB: Add UAS driver")
Signed-off-by: NOliver Neukum <oneukum@suse.com>
Link: https://lore.kernel.org/r/20200916094026.30085-2-oneukum@suse.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 8dba2010
...@@ -662,8 +662,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, ...@@ -662,8 +662,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
if (devinfo->resetting) { if (devinfo->resetting) {
cmnd->result = DID_ERROR << 16; cmnd->result = DID_ERROR << 16;
cmnd->scsi_done(cmnd); cmnd->scsi_done(cmnd);
spin_unlock_irqrestore(&devinfo->lock, flags); goto zombie;
return 0;
} }
/* Find a free uas-tag */ /* Find a free uas-tag */
...@@ -699,6 +698,16 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, ...@@ -699,6 +698,16 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB); cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
err = uas_submit_urbs(cmnd, devinfo); err = uas_submit_urbs(cmnd, devinfo);
/*
* in case of fatal errors the SCSI layer is peculiar
* a command that has finished is a success for the purpose
* of queueing, no matter how fatal the error
*/
if (err == -ENODEV) {
cmnd->result = DID_ERROR << 16;
cmnd->scsi_done(cmnd);
goto zombie;
}
if (err) { if (err) {
/* If we did nothing, give up now */ /* If we did nothing, give up now */
if (cmdinfo->state & SUBMIT_STATUS_URB) { if (cmdinfo->state & SUBMIT_STATUS_URB) {
...@@ -709,6 +718,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, ...@@ -709,6 +718,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
} }
devinfo->cmnd[idx] = cmnd; devinfo->cmnd[idx] = cmnd;
zombie:
spin_unlock_irqrestore(&devinfo->lock, flags); spin_unlock_irqrestore(&devinfo->lock, flags);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册