From 56f334780e02c5c33ce16757a41eb577805ef1a5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:28:01 +0900 Subject: [PATCH] --- yaml --- r: 29492 b: refs/heads/master c: 0ea035a3d1ad948096e205f08f350c03d5cea453 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/scsi/libata-eh.c | 28 ++++++++++++++++++++++++++++ trunk/drivers/scsi/libata-scsi.c | 24 ++++++++++++++++++++++++ trunk/drivers/scsi/libata.h | 1 + 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index ae920906b254..073082446b8b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e8e008e7b5ed8c65675cc9b3e778b8bb909f65ab +refs/heads/master: 0ea035a3d1ad948096e205f08f350c03d5cea453 diff --git a/trunk/drivers/scsi/libata-eh.c b/trunk/drivers/scsi/libata-eh.c index 8ecb8424d7ba..a049bffdf770 100644 --- a/trunk/drivers/scsi/libata-eh.c +++ b/trunk/drivers/scsi/libata-eh.c @@ -666,6 +666,34 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) __ata_eh_qc_complete(qc); } +/** + * ata_eh_detach_dev - detach ATA device + * @dev: ATA device to detach + * + * Detach @dev. + * + * LOCKING: + * None. + */ +static void ata_eh_detach_dev(struct ata_device *dev) +{ + struct ata_port *ap = dev->ap; + unsigned long flags; + + ata_dev_disable(dev); + + spin_lock_irqsave(&ap->host_set->lock, flags); + + dev->flags &= ~ATA_DFLAG_DETACH; + + if (ata_scsi_offline_dev(dev)) { + dev->flags |= ATA_DFLAG_DETACHED; + ap->flags |= ATA_FLAG_SCSI_HOTPLUG; + } + + spin_unlock_irqrestore(&ap->host_set->lock, flags); +} + /** * ata_eh_about_to_do - about to perform eh_action * @ap: target ATA port diff --git a/trunk/drivers/scsi/libata-scsi.c b/trunk/drivers/scsi/libata-scsi.c index da9689b70826..3dc6188af0e8 100644 --- a/trunk/drivers/scsi/libata-scsi.c +++ b/trunk/drivers/scsi/libata-scsi.c @@ -2762,3 +2762,27 @@ void ata_scsi_scan_host(struct ata_port *ap) } } } + +/** + * ata_scsi_offline_dev - offline attached SCSI device + * @dev: ATA device to offline attached SCSI device for + * + * This function is called from ata_eh_hotplug() and responsible + * for taking the SCSI device attached to @dev offline. This + * function is called with host_set lock which protects dev->sdev + * against clearing. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + * + * RETURNS: + * 1 if attached SCSI device exists, 0 otherwise. + */ +int ata_scsi_offline_dev(struct ata_device *dev) +{ + if (dev->sdev) { + scsi_device_set_state(dev->sdev, SDEV_OFFLINE); + return 1; + } + return 0; +} diff --git a/trunk/drivers/scsi/libata.h b/trunk/drivers/scsi/libata.h index 2d704be355cc..e38759fdc183 100644 --- a/trunk/drivers/scsi/libata.h +++ b/trunk/drivers/scsi/libata.h @@ -75,6 +75,7 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); extern struct scsi_transport_template ata_scsi_transport_template; extern void ata_scsi_scan_host(struct ata_port *ap); +extern int ata_scsi_offline_dev(struct ata_device *dev); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen);