linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add support for asynchronous scans to libata
@ 2006-12-08 21:12 Matthew Wilcox
  2006-12-11 15:58 ` Jeff Garzik
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Matthew Wilcox @ 2006-12-08 21:12 UTC (permalink / raw)
  To: linux-scsi, linux-ide, jgarzik

Some of the drivers (AHCI was mentioned to me as a culprit) take a long
time to discover all the devices attached to them.  Even for ones which
are relatively quick, if you put a lot of them in a machine, it will
take a long time in aggregate.  This can be fixed by adding support for
asynchronous scsi scans, which causes the time-consuming portions of
initialisation to take place in threads.

Signed-off-by: Matthew Wilcox <matthew@wil.cx>

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 234197e..3e39e24 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -237,6 +237,8 @@ static struct scsi_host_template ahci_sh
 	.dma_boundary		= AHCI_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.suspend		= ata_scsi_device_suspend,
 	.resume			= ata_scsi_device_resume,
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 377425e..a516eb4 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -116,6 +116,8 @@ static struct scsi_host_template generic
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 720174d..101cf75 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -263,6 +263,8 @@ static struct scsi_host_template piix_sh
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 915a55a..9ece3b7 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5397,6 +5397,13 @@ static struct ata_port * ata_port_add(co
 		return NULL;
 	}
 
+	if (!ent->sht->scan_start) {
+		printk(KERN_WARNING "ata%u: Overriding NULL scan_start\n",
+			port_no);
+		ent->sht->scan_start = ata_scsi_scan_start;
+		ent->sht->scan_finished = ata_scsi_scan_finished;
+	}
+
 	shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
 	if (!shost)
 		return NULL;
@@ -5432,6 +5439,51 @@ void ata_host_init(struct ata_host *host
 	host->ops = ops;
 }
 
+void ata_scsi_scan_start(struct Scsi_Host *shost)
+{
+	struct ata_port *ap = ata_shost_to_port(shost);
+	int rc;
+
+	if (ap->ops->error_handler) {
+		struct ata_eh_info *ehi = &ap->eh_info;
+		unsigned long flags;
+
+		ata_port_probe(ap);
+
+		/* kick EH for boot probing */
+		spin_lock_irqsave(ap->lock, flags);
+
+		ehi->probe_mask = (1 << ATA_MAX_DEVICES) - 1;
+		ehi->action |= ATA_EH_SOFTRESET;
+		ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
+
+		ap->pflags |= ATA_PFLAG_LOADING;
+		ata_port_schedule_eh(ap);
+
+		spin_unlock_irqrestore(ap->lock, flags);
+
+		/* wait for EH to finish */
+		ata_port_wait_eh(ap);
+	} else {
+		DPRINTK("ata%u: bus probe begin\n", ap->id);
+		rc = ata_bus_probe(ap);
+		DPRINTK("ata%u: bus probe end\n", ap->id);
+
+		if (rc) {
+			/* FIXME: do something useful here?
+			 * Current libata behavior will tear down everything
+			 * when the module is removed or the h/w is unplugged.
+			 */
+		}
+	}
+}
+
+int ata_scsi_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+	ata_scsi_scan_host(ata_shost_to_port(shost));
+	return 1;
+}
+
 /**
  *	ata_device_add - Register hardware device with ATA and SCSI layers
  *	@ent: Probe information describing hardware device to be registered
@@ -5549,7 +5601,6 @@ int ata_device_add(const struct ata_prob
 		}
 	}
 
-	/* perform each probe synchronously */
 	DPRINTK("probe begin\n");
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
@@ -5573,48 +5624,7 @@ int ata_device_add(const struct ata_prob
 			 */
 		}
 
-		if (ap->ops->error_handler) {
-			struct ata_eh_info *ehi = &ap->eh_info;
-			unsigned long flags;
-
-			ata_port_probe(ap);
-
-			/* kick EH for boot probing */
-			spin_lock_irqsave(ap->lock, flags);
-
-			ehi->probe_mask = (1 << ATA_MAX_DEVICES) - 1;
-			ehi->action |= ATA_EH_SOFTRESET;
-			ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
-
-			ap->pflags |= ATA_PFLAG_LOADING;
-			ata_port_schedule_eh(ap);
-
-			spin_unlock_irqrestore(ap->lock, flags);
-
-			/* wait for EH to finish */
-			ata_port_wait_eh(ap);
-		} else {
-			DPRINTK("ata%u: bus probe begin\n", ap->id);
-			rc = ata_bus_probe(ap);
-			DPRINTK("ata%u: bus probe end\n", ap->id);
-
-			if (rc) {
-				/* FIXME: do something useful here?
-				 * Current libata behavior will
-				 * tear down everything when
-				 * the module is removed
-				 * or the h/w is unplugged.
-				 */
-			}
-		}
-	}
-
-	/* probes are done, now scan each port's disk(s) */
-	DPRINTK("host probe begin\n");
-	for (i = 0; i < host->n_ports; i++) {
-		struct ata_port *ap = host->ports[i];
-
-		ata_scsi_scan_host(ap);
+		scsi_scan_host(ap->scsi_host);
 	}
 
 	dev_set_drvdata(dev, host);
@@ -6133,6 +6143,8 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
 EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
+EXPORT_SYMBOL_GPL(ata_scsi_scan_start);
+EXPORT_SYMBOL_GPL(ata_scsi_scan_finished);
 EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
 EXPORT_SYMBOL_GPL(ata_scsi_release);
 EXPORT_SYMBOL_GPL(ata_host_intr);
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 1d695df..b10052c 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -346,6 +346,8 @@ static struct scsi_host_template ali_sht
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 5c47a9e..29886f3 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -333,6 +333,8 @@ static struct scsi_host_template amd_sht
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 96a0980..aea075f 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -314,6 +314,8 @@ static struct scsi_host_template artop_s
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 1ce28d2..77b84bd 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -216,6 +216,8 @@ static struct scsi_host_template atiixp_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index b9bbd1d..cb61b80 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -275,6 +275,8 @@ static struct scsi_host_template cmd64x_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 2cd3c0f..e4c21be 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -166,6 +166,8 @@ static struct scsi_host_template cs5520_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index a07cc81..7198fe4 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -180,6 +180,8 @@ static struct scsi_host_template cs5530_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index f8def3f..aada46f 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -184,6 +184,8 @@ static struct scsi_host_template cs5535_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index 247b436..2c89f89 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -135,6 +135,8 @@ static struct scsi_host_template cy82c69
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index ef18c60..0b54288 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -233,6 +233,8 @@ static struct scsi_host_template efar_sh
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 6d3e4c0..69460c5 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -329,6 +329,8 @@ static struct scsi_host_template hpt36x_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index fce3fcd..2eefe43 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -775,6 +775,8 @@ static struct scsi_host_template hpt37x_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 58cfb2b..85db0d1 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -341,6 +341,8 @@ static struct scsi_host_template hpt3x2n
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index 3334d72..4b4eb39 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -118,6 +118,8 @@ static struct scsi_host_template hpt3x3_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 640b8b0..9243f1f 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -34,6 +34,8 @@ static struct scsi_host_template isapnp_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 18ff3e5..2d3b546 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -675,6 +675,8 @@ static struct scsi_host_template it821x_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 52a2bdf..d8ff9e4 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -136,6 +136,8 @@ static struct scsi_host_template jmicron
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	/* Use standard CHS mapping rules */
 	.bios_param		= ata_std_bios_param,
 };
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 10231ef..aaf9a4b 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -135,6 +135,8 @@ static struct scsi_host_template legacy_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index 9dfe3e9..5cf4916 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -166,6 +166,8 @@ static struct scsi_host_template mpiix_s
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index f5672de..8f05a67 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -62,6 +62,8 @@ static struct scsi_host_template netcell
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	/* Use standard CHS mapping rules */
 	.bios_param		= ata_std_bios_param,
 };
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 2a3dbee..f10b8b5 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -156,6 +156,8 @@ static struct scsi_host_template ns87410
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index fc947df..6b4af88 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -231,6 +231,8 @@ static struct scsi_host_template oldpiix
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index a7320ba..ab6a395 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -202,6 +202,8 @@ static struct scsi_host_template opti_sh
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index c6906b4..dcd0ea1 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -359,6 +359,8 @@ static struct scsi_host_template optidma
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index e93ea27..4bf3d86 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -69,6 +69,8 @@ static struct scsi_host_template pcmcia_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index d894d99..8138bd9 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -141,6 +141,8 @@ static struct scsi_host_template pdc2027
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 5ba9eb2..f9003ae 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -269,6 +269,8 @@ static struct scsi_host_template pdc_sht
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 2c3cc0c..8f116e8 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -164,6 +164,8 @@ static struct scsi_host_template qdi_sht
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 1af83d7..19b8d5e 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -227,6 +227,8 @@ static struct scsi_host_template radisys
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 4533b63..758c6a7 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -90,6 +90,8 @@ static struct scsi_host_template rz1000_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 067d9d2..71d024d 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -193,6 +193,8 @@ static struct scsi_host_template sc1200_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index 5bbf76e..6b67756 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -325,6 +325,8 @@ static struct scsi_host_template serverw
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 4a2b72b..d277ed9 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -225,6 +225,8 @@ static struct scsi_host_template sil680_
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index b9ffafb..64d13db 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -545,6 +545,8 @@ static struct scsi_host_template sis_sht
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index 08a6dc8..56b94e5 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -237,6 +237,8 @@ static struct scsi_host_template sl82c10
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index 9640f80..acf464f 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -192,6 +192,8 @@ static struct scsi_host_template triflex
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 1e7be9e..6468fa4 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -295,6 +295,8 @@ static struct scsi_host_template via_sht
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 9021e34..48950c3 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -152,6 +152,8 @@ static struct scsi_host_template adma_at
 	.dma_boundary		= ADMA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 1b8e0eb..4c101a6 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -390,6 +390,8 @@ static struct scsi_host_template mv_sht
 	.dma_boundary		= MV_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index d65ebfd..7f8ebd5 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -157,6 +157,8 @@ static struct scsi_host_template nv_sht
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 72eda51..a9ea5ec 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -122,6 +122,8 @@ static struct scsi_host_template pdc_ata
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 710909d..81756e8 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -143,6 +143,8 @@ static struct scsi_host_template qs_ata_
 	.dma_boundary		= QS_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index ca8d993..a56e727 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -180,6 +180,8 @@ static struct scsi_host_template sil_sht
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.suspend		= ata_scsi_device_suspend,
 	.resume			= ata_scsi_device_resume,
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 169e200..7a40c87 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -380,6 +380,8 @@ static struct scsi_host_template sil24_s
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.suspend		= ata_scsi_device_suspend,
 	.resume			= ata_scsi_device_resume,
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 9d1235b..366616a 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -96,6 +96,8 @@ static struct scsi_host_template sis_sht
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index db32d15..d460417 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -299,6 +299,8 @@ static struct scsi_host_template k2_sata
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 #ifdef CONFIG_PPC_OF
 	.proc_info		= k2_sata_proc_info,
 #endif
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ae7992d..c964b98 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -192,6 +192,8 @@ static struct scsi_host_template pdc_sat
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 5c603ca..fef5b0a 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -90,6 +90,8 @@ static struct scsi_host_template uli_sht
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 1c7f19a..def7ced 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -106,6 +106,8 @@ static struct scsi_host_template svia_sh
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index e654b99..f28152d 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -279,6 +279,8 @@ static struct scsi_host_template vsc_sat
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index abd2deb..6e2a0dc 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -812,6 +812,8 @@ extern int ata_std_bios_param(struct scs
 			      sector_t capacity, int geom[]);
 extern int ata_scsi_slave_config(struct scsi_device *sdev);
 extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
+extern void ata_scsi_scan_start(struct Scsi_Host *shost);
+extern int ata_scsi_scan_finished(struct Scsi_Host *shost, unsigned long time);
 extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
 				       int queue_depth);
 extern struct ata_device *ata_dev_pair(struct ata_device *adev);


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Add support for asynchronous scans to libata
  2006-12-08 21:12 [PATCH] Add support for asynchronous scans to libata Matthew Wilcox
@ 2006-12-11 15:58 ` Jeff Garzik
  2006-12-11 16:09   ` Matthew Wilcox
  2006-12-11 16:18 ` Jeff Garzik
  2007-04-02 13:21 ` James Smart
  2 siblings, 1 reply; 8+ messages in thread
From: Jeff Garzik @ 2006-12-11 15:58 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-scsi, linux-ide

Matthew Wilcox wrote:
> Some of the drivers (AHCI was mentioned to me as a culprit) take a long
> time to discover all the devices attached to them.  Even for ones which
> are relatively quick, if you put a lot of them in a machine, it will
> take a long time in aggregate.  This can be fixed by adding support for
> asynchronous scsi scans, which causes the time-consuming portions of
> initialisation to take place in threads.
> 
> Signed-off-by: Matthew Wilcox <matthew@wil.cx>

The time-consuming portion already takes place in a thread.  Do you mean 
multiple threads?  Or, ATA's scan is in one thread, while work continues 
in other threads?

Patch seems sane, provided that I am educated a bit :)

	Jeff




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Add support for asynchronous scans to libata
  2006-12-11 15:58 ` Jeff Garzik
@ 2006-12-11 16:09   ` Matthew Wilcox
  2006-12-12 14:02     ` Jeff Garzik
  0 siblings, 1 reply; 8+ messages in thread
From: Matthew Wilcox @ 2006-12-11 16:09 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-scsi, linux-ide

On Mon, Dec 11, 2006 at 10:58:06AM -0500, Jeff Garzik wrote:
> The time-consuming portion already takes place in a thread.  Do you mean 
> multiple threads?  Or, ATA's scan is in one thread, while work continues 
> in other threads?
> 
> Patch seems sane, provided that I am educated a bit :)

Each host will be scanned in its own thread.  So boot-up and
initialisation of other devices (eg, USB, networking, PS/2, etc) will
continue.  Drive ordering and numbering is maintained, and the default
configuration right now is to not enable this feature.

We have infrastructure in place to make sure that all discs are found
before we try to start init or autorun RAID.  If there's anywhere we're
missing a call to scsi_complete_async_scans(), it'll affect SCSI as much
as it will IDE, and I'm extremely interested in fixing it.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Add support for asynchronous scans to libata
  2006-12-08 21:12 [PATCH] Add support for asynchronous scans to libata Matthew Wilcox
  2006-12-11 15:58 ` Jeff Garzik
@ 2006-12-11 16:18 ` Jeff Garzik
  2006-12-12  5:02   ` Matthew Wilcox
  2007-04-02 13:21 ` James Smart
  2 siblings, 1 reply; 8+ messages in thread
From: Jeff Garzik @ 2006-12-11 16:18 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-scsi, linux-ide

Matthew Wilcox wrote:
> Some of the drivers (AHCI was mentioned to me as a culprit) take a long
> time to discover all the devices attached to them.  Even for ones which
> are relatively quick, if you put a lot of them in a machine, it will
> take a long time in aggregate.  This can be fixed by adding support for
> asynchronous scsi scans, which causes the time-consuming portions of
> initialisation to take place in threads.
> 
> Signed-off-by: Matthew Wilcox <matthew@wil.cx>

ACK.  I tried to apply the patch, but git-applymbox choked on every 
single file modified.  Quite possibly, its due to a whitespace cleanup 
in Alan territory.

If you would either (a) wait several hours for libata-dev.git#upstream 
to mirror out, and resend, or (b) supply a git:// URL to pull from, I'll 
merge.

	Jeff




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Add support for asynchronous scans to libata
  2006-12-11 16:18 ` Jeff Garzik
@ 2006-12-12  5:02   ` Matthew Wilcox
  2006-12-12  5:14     ` Matthew Wilcox
  0 siblings, 1 reply; 8+ messages in thread
From: Matthew Wilcox @ 2006-12-12  5:02 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-scsi, linux-ide

On Mon, Dec 11, 2006 at 11:18:17AM -0500, Jeff Garzik wrote:
> ACK.  I tried to apply the patch, but git-applymbox choked on every 
> single file modified.  Quite possibly, its due to a whitespace cleanup 
> in Alan territory.
> 
> If you would either (a) wait several hours for libata-dev.git#upstream 
> to mirror out, and resend, or (b) supply a git:// URL to pull from, I'll 
> merge.

Here's a merge against your upstream head.  It's perhaps more of a
conceptual merge as it adds entries to drivers that have been added
since I wrote the patch.  I also added a couple of missing slave_destroy
methods to the newly-added drivers.

Signed-off-by: Matthew Wilcox <matthew@wil.cx>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Add support for asynchronous scans to libata
  2006-12-12  5:02   ` Matthew Wilcox
@ 2006-12-12  5:14     ` Matthew Wilcox
  0 siblings, 0 replies; 8+ messages in thread
From: Matthew Wilcox @ 2006-12-12  5:14 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-scsi, linux-ide

On Mon, Dec 11, 2006 at 10:02:40PM -0700, Matthew Wilcox wrote:
> On Mon, Dec 11, 2006 at 11:18:17AM -0500, Jeff Garzik wrote:
> > ACK.  I tried to apply the patch, but git-applymbox choked on every 
> > single file modified.  Quite possibly, its due to a whitespace cleanup 
> > in Alan territory.
> > 
> > If you would either (a) wait several hours for libata-dev.git#upstream 
> > to mirror out, and resend, or (b) supply a git:// URL to pull from, I'll 
> > merge.
> 
> Here's a merge against your upstream head.  It's perhaps more of a
> conceptual merge as it adds entries to drivers that have been added
> since I wrote the patch.  I also added a couple of missing slave_destroy
> methods to the newly-added drivers.
> 
> Signed-off-by: Matthew Wilcox <matthew@wil.cx>

... this time with patch ...

Add support for asynchronous scans to libata
    
Some of the drivers (AHCI was mentioned to me as a culprit) take a long
time to discover all the devices attached to them.  Even for ones which
are relatively quick, if you put a lot of them in a machine, it will
take a long time in aggregate.  This can be fixed by adding support for
asynchronous scsi scans, which causes the time-consuming portions of
initialisation to take place in threads.
    
Signed-off-by: Matthew Wilcox <matthew@wil.cx>

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index f36da48..bbbec6d 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -242,6 +242,8 @@ static struct scsi_host_template ahci_sht = {
 	.dma_boundary		= AHCI_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.suspend		= ata_scsi_device_suspend,
 	.resume			= ata_scsi_device_resume,
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 908751d..82c182b 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -116,6 +116,8 @@ static struct scsi_host_template generic_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 7959e4c..0d5b132 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -274,6 +274,8 @@ static struct scsi_host_template piix_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 5fffccd..0d80396 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5712,6 +5712,13 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
 		return NULL;
 	}
 
+	if (!ent->sht->scan_start) {
+		printk(KERN_WARNING "ata%u: Overriding NULL scan_start\n",
+			port_no);
+		ent->sht->scan_start = ata_scsi_scan_start;
+		ent->sht->scan_finished = ata_scsi_scan_finished;
+	}
+
 	shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
 	if (!shost)
 		return NULL;
@@ -5747,6 +5754,51 @@ void ata_host_init(struct ata_host *host, struct device *dev,
 	host->ops = ops;
 }
 
+void ata_scsi_scan_start(struct Scsi_Host *shost)
+{
+	struct ata_port *ap = ata_shost_to_port(shost);
+	int rc;
+
+	if (ap->ops->error_handler) {
+		struct ata_eh_info *ehi = &ap->eh_info;
+		unsigned long flags;
+
+		ata_port_probe(ap);
+
+		/* kick EH for boot probing */
+		spin_lock_irqsave(ap->lock, flags);
+
+		ehi->probe_mask = (1 << ATA_MAX_DEVICES) - 1;
+		ehi->action |= ATA_EH_SOFTRESET;
+		ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
+
+		ap->pflags |= ATA_PFLAG_LOADING;
+		ata_port_schedule_eh(ap);
+
+		spin_unlock_irqrestore(ap->lock, flags);
+
+		/* wait for EH to finish */
+		ata_port_wait_eh(ap);
+	} else {
+		DPRINTK("ata%u: bus probe begin\n", ap->id);
+		rc = ata_bus_probe(ap);
+		DPRINTK("ata%u: bus probe end\n", ap->id);
+
+		if (rc) {
+			/* FIXME: do something useful here?
+			 * Current libata behavior will tear down everything
+			 * when the module is removed or the h/w is unplugged.
+			 */
+		}
+	}
+}
+
+int ata_scsi_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+	ata_scsi_scan_host(ata_shost_to_port(shost));
+	return 1;
+}
+
 /**
  *	ata_device_add - Register hardware device with ATA and SCSI layers
  *	@ent: Probe information describing hardware device to be registered
@@ -5863,7 +5915,6 @@ int ata_device_add(const struct ata_probe_ent *ent)
 		}
 	}
 
-	/* perform each probe synchronously */
 	DPRINTK("probe begin\n");
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
@@ -5887,48 +5938,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
 			 */
 		}
 
-		if (ap->ops->error_handler) {
-			struct ata_eh_info *ehi = &ap->eh_info;
-			unsigned long flags;
-
-			ata_port_probe(ap);
-
-			/* kick EH for boot probing */
-			spin_lock_irqsave(ap->lock, flags);
-
-			ehi->probe_mask = (1 << ATA_MAX_DEVICES) - 1;
-			ehi->action |= ATA_EH_SOFTRESET;
-			ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
-
-			ap->pflags |= ATA_PFLAG_LOADING;
-			ata_port_schedule_eh(ap);
-
-			spin_unlock_irqrestore(ap->lock, flags);
-
-			/* wait for EH to finish */
-			ata_port_wait_eh(ap);
-		} else {
-			DPRINTK("ata%u: bus probe begin\n", ap->id);
-			rc = ata_bus_probe(ap);
-			DPRINTK("ata%u: bus probe end\n", ap->id);
-
-			if (rc) {
-				/* FIXME: do something useful here?
-				 * Current libata behavior will
-				 * tear down everything when
-				 * the module is removed
-				 * or the h/w is unplugged.
-				 */
-			}
-		}
-	}
-
-	/* probes are done, now scan each port's disk(s) */
-	DPRINTK("host probe begin\n");
-	for (i = 0; i < host->n_ports; i++) {
-		struct ata_port *ap = host->ports[i];
-
-		ata_scsi_scan_host(ap);
+		scsi_scan_host(ap->scsi_host);
 	}
 
 	dev_set_drvdata(dev, host);
@@ -6448,6 +6458,8 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
 EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
+EXPORT_SYMBOL_GPL(ata_scsi_scan_start);
+EXPORT_SYMBOL_GPL(ata_scsi_scan_finished);
 EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
 EXPORT_SYMBOL_GPL(ata_scsi_release);
 EXPORT_SYMBOL_GPL(ata_host_intr);
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 2035417..3d9d69b 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -344,6 +344,8 @@ static struct scsi_host_template ali_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index a6b3300..764d231 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -333,6 +333,8 @@ static struct scsi_host_template amd_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 37bc132..6e16901 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -314,6 +314,8 @@ static struct scsi_host_template artop_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 6f6672c..cb0a2e0 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -216,6 +216,8 @@ static struct scsi_host_template atiixp_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 15841a5..ac014c9 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -275,6 +275,8 @@ static struct scsi_host_template cmd64x_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 476b879..71c04e5 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -166,6 +166,8 @@ static struct scsi_host_template cs5520_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 9b9d911..f1ccfe0 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -180,6 +180,8 @@ static struct scsi_host_template cs5530_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index e3efec4..97fefb2 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -184,6 +184,8 @@ static struct scsi_host_template cs5535_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index e2a9569..dde9ef9 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -135,6 +135,8 @@ static struct scsi_host_template cy82c693_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index edf8a63..6d5eb82 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -233,6 +233,8 @@ static struct scsi_host_template efar_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 8cf167e..db49053 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -337,6 +337,8 @@ static struct scsi_host_template hpt36x_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index e51651b..6347b52 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -775,6 +775,8 @@ static struct scsi_host_template hpt37x_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index f6817b4..4739f3b 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -341,6 +341,8 @@ static struct scsi_host_template hpt3x2n_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index 5caf167..19c0eba 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -118,6 +118,8 @@ static struct scsi_host_template hpt3x3_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index a97d55a..f2bc867 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -34,6 +34,8 @@ static struct scsi_host_template isapnp_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index 7e9a416..4853d7b 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -245,6 +245,9 @@ static struct scsi_host_template it8213_sht = {
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 0b56ff3..235c230 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -673,6 +673,8 @@ static struct scsi_host_template it821x_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index cb89241..1889158 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -117,6 +117,8 @@ static struct scsi_host_template ixp4xx_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index efb1b6d..7d19bc9 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -135,6 +135,8 @@ static struct scsi_host_template jmicron_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	/* Use standard CHS mapping rules */
 	.bios_param		= ata_std_bios_param,
 };
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index c7d1738..4462b58 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -135,6 +135,8 @@ static struct scsi_host_template legacy_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index af93533..601618d 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -101,6 +101,8 @@ static struct scsi_host_template marvell_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	/* Use standard CHS mapping rules */
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 8b7019a..bc5b802 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -280,6 +280,9 @@ static struct scsi_host_template mpc52xx_ata_sht = {
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
+	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index 4ccca93..fc6d072 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -166,6 +166,8 @@ static struct scsi_host_template mpiix_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index cf7fe03..08fc7a5 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -61,6 +61,8 @@ static struct scsi_host_template netcell_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	/* Use standard CHS mapping rules */
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index c3032eb..6ffa2e2 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -156,6 +156,8 @@ static struct scsi_host_template ns87410_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 10ac3cc..b2d943e 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -231,6 +231,8 @@ static struct scsi_host_template oldpiix_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index c2988b0..575c4b4 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -178,6 +178,8 @@ static struct scsi_host_template opti_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 80d111c..28a041a 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -359,6 +359,8 @@ static struct scsi_host_template optidma_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 9ed7f58..67236a3 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -69,6 +69,8 @@ static struct scsi_host_template pcmcia_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index 76dd1c9..3152b90 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -141,6 +141,8 @@ static struct scsi_host_template pdc2027x_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index ad691b9..3174346 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -269,6 +269,8 @@ static struct scsi_host_template pdc202xx_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index 443b1d8..9849893 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -78,6 +78,8 @@ static struct scsi_host_template pata_platform_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 36f621a..7857ef1 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -164,6 +164,8 @@ static struct scsi_host_template qdi_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 065541d..29842cc 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -227,6 +227,8 @@ static struct scsi_host_template radisys_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 3677c64..9167c39 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -90,6 +90,8 @@ static struct scsi_host_template rz1000_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index a3b35bc..3c59b46 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -193,6 +193,8 @@ static struct scsi_host_template sc1200_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index 8019197..2406ed7 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -325,6 +325,8 @@ static struct scsi_host_template serverworks_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index ae07f63..c6855e0 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -225,6 +225,8 @@ static struct scsi_host_template sil680_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index c434c4e..45409ad 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -545,6 +545,8 @@ static struct scsi_host_template sis_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index e94f515..4607150 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -237,6 +237,8 @@ static struct scsi_host_template sl82c105_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index a142971..fcc3964 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -192,6 +192,8 @@ static struct scsi_host_template triflex_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 9905fa8..571e66c 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -297,6 +297,8 @@ static struct scsi_host_template via_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.resume			= ata_scsi_device_resume,
 	.suspend		= ata_scsi_device_suspend,
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index cd5560f..24092b9 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -133,6 +133,8 @@ static struct scsi_host_template winbond_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 9021e34..48950c3 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -152,6 +152,8 @@ static struct scsi_host_template adma_ata_sht = {
 	.dma_boundary		= ADMA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 1b8e0eb..4c101a6 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -390,6 +390,8 @@ static struct scsi_host_template mv_sht = {
 	.dma_boundary		= MV_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 49f8ff2..2dbb89a 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -310,6 +310,8 @@ static struct scsi_host_template nv_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index f055874..f25dba5 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -129,6 +129,8 @@ static struct scsi_host_template pdc_ata_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 710909d..81756e8 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -143,6 +143,8 @@ static struct scsi_host_template qs_ata_sht = {
 	.dma_boundary		= QS_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 7808d03..29b283b 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -180,6 +180,8 @@ static struct scsi_host_template sil_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.suspend		= ata_scsi_device_suspend,
 	.resume			= ata_scsi_device_resume,
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 5aa288d..8372ce7 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -385,6 +385,8 @@ static struct scsi_host_template sil24_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 	.suspend		= ata_scsi_device_suspend,
 	.resume			= ata_scsi_device_resume,
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index c90fb13..feed5ab 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -99,6 +99,8 @@ static struct scsi_host_template sis_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index db32d15..d460417 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -299,6 +299,8 @@ static struct scsi_host_template k2_sata_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 #ifdef CONFIG_PPC_OF
 	.proc_info		= k2_sata_proc_info,
 #endif
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ae7992d..c964b98 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -192,6 +192,8 @@ static struct scsi_host_template pdc_sata_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 5c603ca..fef5b0a 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -90,6 +90,8 @@ static struct scsi_host_template uli_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 8c2335c..e045ba1 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -106,6 +106,8 @@ static struct scsi_host_template svia_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index e654b99..f28152d 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -279,6 +279,8 @@ static struct scsi_host_template vsc_sata_sht = {
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
+	.scan_start		= ata_scsi_scan_start,
+	.scan_finished		= ata_scsi_scan_finished,
 	.bios_param		= ata_std_bios_param,
 };
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 9356322..bdf69a4 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -822,6 +822,8 @@ extern int ata_std_bios_param(struct scsi_device *sdev,
 			      sector_t capacity, int geom[]);
 extern int ata_scsi_slave_config(struct scsi_device *sdev);
 extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
+extern void ata_scsi_scan_start(struct Scsi_Host *shost);
+extern int ata_scsi_scan_finished(struct Scsi_Host *shost, unsigned long time);
 extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
 				       int queue_depth);
 extern struct ata_device *ata_dev_pair(struct ata_device *adev);

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Add support for asynchronous scans to libata
  2006-12-11 16:09   ` Matthew Wilcox
@ 2006-12-12 14:02     ` Jeff Garzik
  0 siblings, 0 replies; 8+ messages in thread
From: Jeff Garzik @ 2006-12-12 14:02 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-scsi, linux-ide, Andrew Morton

Matthew Wilcox wrote:
> On Mon, Dec 11, 2006 at 10:58:06AM -0500, Jeff Garzik wrote:
>> The time-consuming portion already takes place in a thread.  Do you mean 
>> multiple threads?  Or, ATA's scan is in one thread, while work continues 
>> in other threads?
>>
>> Patch seems sane, provided that I am educated a bit :)
> 
> Each host will be scanned in its own thread.  So boot-up and
> initialisation of other devices (eg, USB, networking, PS/2, etc) will
> continue.  Drive ordering and numbering is maintained, and the default
> configuration right now is to not enable this feature.
> 
> We have infrastructure in place to make sure that all discs are found
> before we try to start init or autorun RAID.  If there's anywhere we're
> missing a call to scsi_complete_async_scans(), it'll affect SCSI as much
> as it will IDE, and I'm extremely interested in fixing it.

oh, err, hum.

libata uses one scsihost per port, not one-per-controller, so it won't 
work like you think.

This will conflict with AHCI's staggered spin-up, at least.

	Jeff




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Add support for asynchronous scans to libata
  2006-12-08 21:12 [PATCH] Add support for asynchronous scans to libata Matthew Wilcox
  2006-12-11 15:58 ` Jeff Garzik
  2006-12-11 16:18 ` Jeff Garzik
@ 2007-04-02 13:21 ` James Smart
  2 siblings, 0 replies; 8+ messages in thread
From: James Smart @ 2007-04-02 13:21 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-scsi, linux-ide, jgarzik

Matt,

Have your resolved the unload race conditions yet?

We'd like to update lpfc for the async scans, but our testing gets blocked
very quickly by the bugs. The bugs are not necessarily specific to lpfc
or to FC.

Stack traces are below. Simple ismod/rmmod loop can trigger them....

-- james s



First one is an rmmod while lpfc is active in it's scan_start function.
I think we're in a sleep waiting for the board to be ready when the driver
is yanked out from underneath us.

Second one is an rmmod while do_scsi_scan_host is in a loop calling
scan_finished.

Third one is an rmmod immediately after completion of do_scan_async.


STACK TRACE 1
-------------

BUG: unable to handle kernel paging request at virtual address f8941836
  printing eip:
f8941836
*pde = 37e59067
Oops: 0000 [#1]
SMP
Modules linked in: autofs4 hidp rfcomm l2cap bluetooth sunrpc ipv6 dm_mirror dm_mod video sbs i2c_e6
  printing eip:
f8941836
*pde = 37e59067
  chipreg pcspkr tg3 scsi_transport_fc mptspi mptscsih mptbase scsi_transport_spi sd_mod scsi_mod exd
CPU:    2
EIP:    0060:[<f8941836>]    Not tainted VLI
EFLAGS: 00010246   (2.6.20-rc7-jimp #1)
EIP is at 0xf8941836
eax: 00000000   ebx: 00000000   ecx: c1900000   edx: 00000286
esi: f7ab6000   edi: f887158d   ebp: f7ab62e8   esp: ecec9f30
ds: 007b   es: 007b   ss: 0068
Process scsi_scan_6 (pid: 15927, ti=ecec9000 task=f2309000 task.ti=ecec9000)
Stack: c04a2183 f65b6cc4 f8963c80 f8963c80 f71e38d0 ffffffef c04a1cef 00008180
        00000008 f6e4aa00 00000000 00000046 00000000 f7ab62e8 f7ab6000 f887158d
        f75fa3e0 f7ab62e8 f7ab6000 f887158d f75fa3e0 f894d6dc f89593e4 f7ab6000
Call Trace:
  [<c04a2183>] sysfs_dirent_exist+0x20/0x5f
  [<c04a1cef>] sysfs_add_file+0x66/0x70
  [<f887158d>] do_scan_async+0x0/0x126 [scsi_mod]
  [<f887158d>] do_scan_async+0x0/0x126 [scsi_mod]
  [<f88713e0>] do_scsi_scan_host+0x30/0x8b [scsi_mod]
  [<f88715aa>] do_scan_async+0x1d/0x126 [scsi_mod]
  [<c041f7b4>] complete+0x39/0x48
  [<f887158d>] do_scan_async+0x0/0x126 [scsi_mod]
  [<c0436924>] kthread+0xb0/0xd8
  [<c0436874>] kthread+0x0/0xd8
  [<c0404977>] kernel_thread_helper+0x7/0x10
  =======================
Code:  Bad EIP value.
EIP: [<f8941836>] 0xf8941836 SS:ESP 0068:ecec9f30
  <0>Oops: 0000 [#2]
SMP
Modules linked in: autofs4 hidp rfcomm l2cap bluetooth sunrpc ipv6 dm_mirror dm_mod video sbs i2c_ed
CPU:    3
EIP:    0060:[<f8941836>]    Not tainted VLI
EFLAGS: 00010246   (2.6.20-rc7-jimp #1)
EIP is at 0xf8941836
eax: 00000000   ebx: 00000000   ecx: c1902000   edx: 00000286
esi: f74ff000   edi: f887158d   ebp: f74ff2e8   esp: ec3c1f30
ds: 007b   es: 007b   ss: 0068
Process scsi_scan_5 (pid: 15919, ti=ec3c1000 task=f7b92000 task.ti=ec3c1000)
Stack: c04a2183 ece3821c f8963c80 f8963c80 f6b3942c ffffffef c04a1cef 00008180
        00000008 f6efea00 00000000 00000046 00000002 f74ff2e8 f74ff000 f887158d
        f7897de0 f74ff2e8 f74ff000 f887158d f7897de0 f894d6dc f89593e4 f74ff000
Call Trace:
  [<c04a2183>] sysfs_dirent_exist+0x20/0x5f
  [<c04a1cef>] sysfs_add_file+0x66/0x70
  [<f887158d>] do_scan_async+0x0/0x126 [scsi_mod]
  [<f887158d>] do_scan_async+0x0/0x126 [scsi_mod]
  [<f88713e0>] do_scsi_scan_host+0x30/0x8b [scsi_mod]
  [<f88715aa>] do_scan_async+0x1d/0x126 [scsi_mod]
  [<f887158d>] do_scan_async+0x0/0x126 [scsi_mod]
  [<c0436924>] kthread+0xb0/0xd8
  [<c0436874>] kthread+0x0/0xd8
  [<c0404977>] kernel_thread_helper+0x7/0x10
  =======================

STACK TRACE 2
-------------

BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000
  printing eip:
c0548435
*pde = 00000000
Oops: 0000 [#3]
SMP
Modules linked in: lpfc autofs4 hidp rfcomm l2cap bluetooth sunrpc ipv6 dm_mirror dm_mod video sbs d
CPU:    3
EIP:    0060:[<c0548435>]    Not tainted VLI
EFLAGS: 00010202   (2.6.20-rc7-jimp #1)
EIP is at make_class_name+0x27/0x7d
eax: 00000000   ebx: ffffffff   ecx: ffffffff   edx: 0000000b
esi: f887c29a   edi: 00000000   ebp: 00000000   esp: edd27ec4
ds: 007b   es: 007b   ss: 0068
Process fc_wq_7 (pid: 16050, ti=edd27000 task=f68b4550 task.ti=edd27000)
Stack: f65d35f8 f8889e20 f65d35f8 f65d35f0 f8889da0 c0548616 00000000 f65d35f0
        f69f0030 f6fdc000 00000000 c054869c f65d3400 f88720f8 f65d3400 f69f0030
        f8872152 f65d3400 f69f0000 f88721c9 f6fdc014 f6d1d848 f8872233 f8872247
Call Trace:
  [<c0548616>] class_device_del+0x8c/0x10a
  [<c054869c>] class_device_unregister+0x8/0x10
  [<f88720f8>] __scsi_remove_device+0x1d/0x60 [scsi_mod]
  [<f8872152>] scsi_remove_device+0x17/0x20 [scsi_mod]
  [<f88721c9>] __scsi_remove_target+0x6e/0xa1 [scsi_mod]
  [<f8872233>] __remove_child+0x0/0x18 [scsi_mod]
  [<f8872247>] __remove_child+0x14/0x18 [scsi_mod]
  [<c0545dc0>] device_for_each_child+0x1a/0x3c
  [<f887222a>] scsi_remove_target+0x2e/0x37 [scsi_mod]
  [<f88b7ae6>] fc_rport_final_delete+0x51/0x9a [scsi_transport_fc]
  [<c04339ff>] run_workqueue+0x85/0x125
  [<c042eb72>] do_sigaction+0x10f/0x149
  [<f88b7a95>] fc_rport_final_delete+0x0/0x9a [scsi_transport_fc]
  [<c0434359>] worker_thread+0xf9/0x124
  [<c0421072>] default_wake_function+0x0/0xc
  [<c0434260>] worker_thread+0x0/0x124
  [<c0436924>] kthread+0xb0/0xd8
  [<c0436874>] kthread+0x0/0xd8
  [<c0404977>] kernel_thread_helper+0x7/0x10
  =======================
Code: 5b 04 5b c3 55 31 ed 57 89 c7 56 89 c6 53 83 cb ff 83 ec 04 89 d9 89 14 24 89 e8 f2 ae f7 d1

STACK TRACE 3
-------------

BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000
  printing eip:
00000000
*pde = 00000000
Oops: 0000 [#1]
SMP
Modules linked in: lpfc autofs4 hidp rfcomm l2cap bluetooth sunrpc ipv6 dm_mirror dm_mod video sbs d
CPU:    0
EIP:    0060:[<00000000>]    Not tainted VLI
EFLAGS: 00010206   (2.6.20-rc7-jimp #1)
EIP is at _stext+0x3fbffc70/0x14
eax: f64c2830   ebx: f64c2830   ecx: f887181b   edx: f6ee1414
esi: f6ee1414   edi: f6ee1414   ebp: c054a70a   esp: eb5f4e98
ds: 007b   es: 007b   ss: 0068
Process vol_id (pid: 32421, ti=eb5f4000 task=e50c1550 task.ti=eb5f4000)
Stack: c054a625 00000000 c04daa3e ec23d4c0 e9fa4000 f6ee1400 f6ee1414 e7df8800
        f887184f e7df8a84 f6ee1400 00000286 e7df8800 c0433bc4 f8871a7c f6ee1414
        e7df890c c06c44a8 c06c4440 f6ee148c c0433bc4 c0545cc9 ffffffff eb1f8e90
Call Trace:
  [<c054a625>] attribute_container_device_trigger+0x33/0xa2
  [<c04daa3e>] kobject_cleanup+0x3e/0x5e
  [<f887184f>] scsi_target_reap_usercontext+0x34/0x89 [scsi_mod]
  [<c0433bc4>] execute_in_process_context+0x16/0x38
  [<f8871a7c>] scsi_device_dev_release_usercontext+0x92/0xba [scsi_mod]
  [<c0433bc4>] execute_in_process_context+0x16/0x38
  [<c0545cc9>] device_release+0x26/0x6b
  [<c04daa3e>] kobject_cleanup+0x3e/0x5e
  [<c04daa5e>] kobject_release+0x0/0x8
  [<c04db507>] kref_put+0x60/0x6d
  [<c04860fa>] invalidate_bh_lru+0x26/0x37
  [<f886a0ac>] scsi_device_put+0x16/0x2e [scsi_mod]
  [<f88322d7>] scsi_disk_put+0x22/0x2e [sd_mod]
  [<f8832c19>] sd_release+0x69/0x70 [sd_mod]
  [<c04570bb>] truncate_inode_pages+0x17/0x1c
  [<c048a4be>] __blkdev_put+0x5b/0x103
  [<c046c70f>] __fput+0xa5/0x15b
  [<c046a23b>] filp_close+0x51/0x58
  [<c046b168>] sys_close+0x6d/0xa3
  [<c0403d9c>] syscall_call+0x7/0xb
  =======================
Code:  Bad EIP value.
EIP: [<00000000>] _stext+0x3fbffc70/0x14 SS:ESP 0068:eb5f4e98


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-04-02 13:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-08 21:12 [PATCH] Add support for asynchronous scans to libata Matthew Wilcox
2006-12-11 15:58 ` Jeff Garzik
2006-12-11 16:09   ` Matthew Wilcox
2006-12-12 14:02     ` Jeff Garzik
2006-12-11 16:18 ` Jeff Garzik
2006-12-12  5:02   ` Matthew Wilcox
2006-12-12  5:14     ` Matthew Wilcox
2007-04-02 13:21 ` James Smart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).