[PATCH 04/15] libata-hp: connect ATA hotplug events to SCSI hotplug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Schedule SCSI plug/unplug operations from EH with appropriate hotplug
flags and run scsi hotplug from ata_hotplug_wq on EH completion.  On
host initialization, SCSI hotplug starts disabled until
ATA_HOTPLUG_RUNNING flag is set on boot probing completion.  This is
to avoid running multiple SCSI plug/unplug operations simultaneously.

Signed-off-by: Tejun Heo <htejun@xxxxxxxxx>

---

 drivers/scsi/libata-core.c |    3 +++
 drivers/scsi/libata-eh.c   |   12 ++++++++++++
 include/linux/libata.h     |    1 +
 3 files changed, 16 insertions(+), 0 deletions(-)

dce4c2009a3abc3fa370b639feda83e09c96dc9c
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 85f0600..91a01ca 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -4896,6 +4896,7 @@ static void ata_host_init(struct ata_por
 	ap->last_ctl = 0xFF;
 
 	INIT_WORK(&ap->port_task, NULL, NULL);
+	INIT_WORK(&ap->hotplug_task, ata_eh_scsi_hotplug, ap);
 	INIT_LIST_HEAD(&ap->eh_done_q);
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++)
@@ -5088,6 +5089,8 @@ int ata_device_add(const struct ata_prob
 		struct ata_port *ap = host_set->ports[i];
 
 		ata_scsi_scan_host(ap);
+		/* boot probe done, allow hotplugging */
+		ata_set_hotplug_flags(ap, ATA_HOTPLUG_RUNNING);
 	}
 
 	dev_set_drvdata(dev, host_set);
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index ee46221..64edf48 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -240,6 +240,12 @@ int ata_scsi_error(struct Scsi_Host *hos
 	/* bookkeeping for hotplug */
 	ata_clr_hotplug_flags(ap, ATA_HOTPLUG_PROBE | ATA_HOTPLUG_DID_PROBE);
 
+	/* schedule SCSI hotplug if requested */
+	if (ap->hotplug_flags & ATA_HOTPLUG_RUNNING &&
+	    ap->hotplug_flags & (ATA_HOTPLUG_SCSI_PLUG |
+				 ATA_HOTPLUG_SCSI_UNPLUG))
+		queue_work(ata_hotplug_wq, &ap->hotplug_task);
+
 	DPRINTK("EXIT\n");
 	return 0;
 }
@@ -1434,6 +1440,9 @@ void ata_eh_hotplug(struct ata_port *ap)
 		dev->flags &= ~ATA_DFLAG_DETACH_ATA;
 		ata_scsi_offline_dev(ap, dev);
 		spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+		/* schedule SCSI unplug */
+		ata_set_hotplug_flags(ap, ATA_HOTPLUG_SCSI_UNPLUG);
 	}
 
 	/* probe requested? */
@@ -1530,4 +1539,7 @@ void ata_eh_scsi_hotplug(void *data)
 		ata_clr_hotplug_flags(ap, ATA_HOTPLUG_SCSI_PLUG);
 		ata_scsi_scan_host(ap);
 	}
+
+	/* schedule SCSI plug */
+	ata_set_hotplug_flags(ap, ATA_HOTPLUG_SCSI_PLUG);
 }
diff --git a/include/linux/libata.h b/include/linux/libata.h
index b9dd793..f145f0e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -482,6 +482,7 @@ struct ata_port {
 	struct list_head	eh_done_q;
 
 	unsigned long		hotplug_flags;
+	struct work_struct	hotplug_task;
 
 	void			*private_data;
 };
-- 
1.2.4


-
: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux