If we encounter an error during initial VPD page scan we should be setting the 'skip_vpd_pages' bit to avoid further accesses. Any errors during rescan should be ignored, as we might encounter temporary I/O errors during rescan. Signed-off-by: Hannes Reinecke <hare@xxxxxxxx> --- drivers/scsi/scsi.c | 9 ++++++++- drivers/scsi/scsi_priv.h | 2 +- drivers/scsi/scsi_scan.c | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 1deb6ad..1ff4a0b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -770,13 +770,14 @@ EXPORT_SYMBOL_GPL(scsi_get_vpd_page); /** * scsi_attach_vpd - Attach Vital Product Data to a SCSI device structure * @sdev: The device to ask + * @first_scan: true if called during initial scan * * Attach the 'Device Identification' VPD page (0x83) and the * 'Unit Serial Number' VPD page (0x80) to a SCSI device * structure. This information can be used to identify the device * uniquely. */ -void scsi_attach_vpd(struct scsi_device *sdev) +void scsi_attach_vpd(struct scsi_device *sdev, bool first_scan) { int result, i; int vpd_len = SCSI_VPD_PG_LEN; @@ -796,6 +797,8 @@ retry_pg0: result = scsi_vpd_inquiry(sdev, vpd_buf, 0, vpd_len); if (result < 0) { kfree(vpd_buf); + if (first_scan) + sdev->skip_vpd_pages = 1; return; } if (result > vpd_len) { @@ -822,6 +825,8 @@ retry_pg80: result = scsi_vpd_inquiry(sdev, vpd_buf, 0x80, vpd_len); if (result < 0) { kfree(vpd_buf); + if (first_scan) + sdev->skip_vpd_pages = 1; return; } if (result > vpd_len) { @@ -851,6 +856,8 @@ retry_pg83: result = scsi_vpd_inquiry(sdev, vpd_buf, 0x83, vpd_len); if (result < 0) { kfree(vpd_buf); + if (first_scan) + sdev->skip_vpd_pages = 1; return; } if (result > vpd_len) { diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 6c3db56..0c4cc6d 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -31,7 +31,7 @@ extern void scsi_exit_hosts(void); /* scsi.c */ extern int scsi_setup_command_freelist(struct Scsi_Host *shost); extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); -void scsi_attach_vpd(struct scsi_device *sdev); +void scsi_attach_vpd(struct scsi_device *sdev, bool first_scan); #ifdef CONFIG_SCSI_LOGGING void scsi_log_send(struct scsi_cmnd *cmd); void scsi_log_completion(struct scsi_cmnd *cmd, int disposition); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index e0a78f5..dcc08ad 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -997,7 +997,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, } if (sdev->scsi_level >= SCSI_3) - scsi_attach_vpd(sdev); + scsi_attach_vpd(sdev, true); sdev->max_queue_depth = sdev->queue_depth; @@ -1536,7 +1536,7 @@ void scsi_rescan_device(struct device *dev) device_lock(dev); - scsi_attach_vpd(sdev); + scsi_attach_vpd(sdev, false); if (sdev->handler && sdev->handler->rescan) sdev->handler->rescan(sdev); -- 1.8.5.6 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html