Commit 7d613cda authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

[PATCH] sd_shutdown cannot be called when in state SDEV_DEL

sd_remove calls sd_shutdown to finish I/O to the disc.  However, the
state model puts the device in SDEV_DEL before triggering the
sd_remove (which won't allow any further I/O at all).

Fix by making SDEV_CANCEL the intermediate state and only transitioning to 
SDEV_DEL after calling device_del().
parent de706cdb
......@@ -977,7 +977,7 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
*/
int scsi_device_get(struct scsi_device *sdev)
{
if (sdev->sdev_state == SDEV_DEL)
if (sdev->sdev_state == SDEV_DEL || sdev->sdev_state == SDEV_CANCEL)
return -ENXIO;
if (!get_device(&sdev->sdev_gendev))
return -ENXIO;
......
......@@ -502,18 +502,19 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
**/
void scsi_remove_device(struct scsi_device *sdev)
{
if (sdev->sdev_state == SDEV_RUNNING || sdev->sdev_state == SDEV_CANCEL) {
scsi_device_set_state(sdev, SDEV_DEL);
if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
return;
class_device_unregister(&sdev->sdev_classdev);
if (sdev->transport_classdev.class)
class_device_unregister(&sdev->transport_classdev);
device_del(&sdev->sdev_gendev);
scsi_device_set_state(sdev, SDEV_DEL);
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
if (sdev->host->transportt->cleanup)
sdev->host->transportt->cleanup(sdev);
put_device(&sdev->sdev_gendev);
}
}
int scsi_register_driver(struct device_driver *drv)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment