linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tejun Heo <htejun@gmail.com>
To: jeff@garzik.org, alan@lxorguk.ukuu.org.uk,
	linux-ide@vger.kernel.org, brking@linux.vnet.ibm.com
Cc: Tejun Heo <htejun@gmail.com>
Subject: [PATCH 02/12] libata: separate out ata_host_start()
Date: Wed, 11 Apr 2007 15:42:04 +0900	[thread overview]
Message-ID: <11762737243666-git-send-email-htejun@gmail.com> (raw)
In-Reply-To: <1176273724198-git-send-email-htejun@gmail.com>

Separate out ata_host_start() from ata_device_add().  ata_host_start()
calls ->port_start on each port if available and freezes the port.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
 drivers/ata/libata-core.c |   74 +++++++++++++++++++++++++++++++++++++--------
 include/linux/libata.h    |    2 +
 2 files changed, 63 insertions(+), 13 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 542e9ea..cf4a724 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5809,11 +5809,14 @@ static void ata_host_release(struct device *gendev, void *res)
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 
-		if (ap && ap->ops->port_stop)
+		if (!ap)
+			continue;
+
+		if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop)
 			ap->ops->port_stop(ap);
 	}
 
-	if (host->ops->host_stop)
+	if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop)
 		host->ops->host_stop(host);
 
 	for (i = 0; i < host->n_ports; i++) {
@@ -5833,6 +5836,56 @@ static void ata_host_release(struct device *gendev, void *res)
 }
 
 /**
+ *	ata_host_start - start and freeze ports of an ATA host
+ *	@host: ATA host to start ports for
+ *
+ *	Start and then freeze ports of @host.  Started status is
+ *	recorded in host->flags, so this function can be called
+ *	multiple times.  Ports are guaranteed to get started only
+ *	once.
+ *
+ *	LOCKING:
+ *	Inherited from calling layer (may sleep).
+ *
+ *	RETURNS:
+ *	0 if all ports are started successfully, -errno otherwise.
+ */
+int ata_host_start(struct ata_host *host)
+{
+	int i, rc;
+
+	if (host->flags & ATA_HOST_STARTED)
+		return 0;
+
+	for (i = 0; i < host->n_ports; i++) {
+		struct ata_port *ap = host->ports[i];
+
+		if (ap->ops->port_start) {
+			rc = ap->ops->port_start(ap);
+			if (rc) {
+				ata_port_printk(ap, KERN_ERR, "failed to "
+						"start port (errno=%d)\n", rc);
+				goto err_out;
+			}
+		}
+
+		ata_eh_freeze_port(ap);
+	}
+
+	host->flags |= ATA_HOST_STARTED;
+	return 0;
+
+ err_out:
+	while (--i >= 0) {
+		struct ata_port *ap = host->ports[i];
+
+		if (ap->ops->port_stop)
+			ap->ops->port_stop(ap);
+	}
+	return rc;
+}
+
+/**
  *	ata_sas_host_init - Initialize a host struct
  *	@host:	host to initialize
  *	@dev:	device host is attached to
@@ -5921,14 +5974,6 @@ int ata_device_add(const struct ata_probe_ent *ent)
 			continue;
 		}
 
-		/* start port */
-		rc = ap->ops->port_start(ap);
-		if (rc) {
-			host->ports[i] = NULL;
-			scsi_host_put(ap->scsi_host);
-			goto err_out;
-		}
-
 		/* Report the secondary IRQ for second channel legacy */
 		if (i == 1 && ent->irq2)
 			irq_line = ent->irq2;
@@ -5946,11 +5991,13 @@ int ata_device_add(const struct ata_probe_ent *ent)
 				ap->ioaddr.ctl_addr,
 				ap->ioaddr.bmdma_addr,
 				irq_line);
-
-		/* freeze port before requesting IRQ */
-		ata_eh_freeze_port(ap);
 	}
 
+	/* start ports */
+	rc = ata_host_start(host);
+	if (rc)
+		goto err_out;
+
 	/* obtain irq, that may be shared between channels */
 	rc = devm_request_irq(dev, ent->irq, ent->port_ops->irq_handler,
 			      ent->irq_flags, DRV_NAME, host);
@@ -6436,6 +6483,7 @@ EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
 EXPORT_SYMBOL_GPL(ata_std_bios_param);
 EXPORT_SYMBOL_GPL(ata_std_ports);
 EXPORT_SYMBOL_GPL(ata_host_init);
+EXPORT_SYMBOL_GPL(ata_host_start);
 EXPORT_SYMBOL_GPL(ata_device_add);
 EXPORT_SYMBOL_GPL(ata_host_detach);
 EXPORT_SYMBOL_GPL(ata_sg_init);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ced9dd5..bda26e8 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -210,6 +210,7 @@ enum {
 
 	/* host set flags */
 	ATA_HOST_SIMPLEX	= (1 << 0),	/* Host is simplex, one DMA channel per host only */
+	ATA_HOST_STARTED	= (1 << 1),	/* Host started */
 
 	/* various lengths of time */
 	ATA_TMOUT_BOOT		= 30 * HZ,	/* heuristic */
@@ -732,6 +733,7 @@ extern int ata_pci_device_resume(struct pci_dev *pdev);
 #endif
 extern int ata_pci_clear_simplex(struct pci_dev *pdev);
 #endif /* CONFIG_PCI */
+extern int ata_host_start(struct ata_host *host);
 extern int ata_device_add(const struct ata_probe_ent *ent);
 extern void ata_host_detach(struct ata_host *host);
 extern void ata_host_init(struct ata_host *, struct device *,
-- 
1.5.0.3



  parent reply	other threads:[~2007-04-11  6:42 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-11  6:42 [PATCHSET] libata: implement new initialization model, take #4 Tejun Heo
2007-04-11  6:42 ` [PATCH 01/12] libata: allocate ap separately from shost Tejun Heo
2007-04-11  6:42 ` Tejun Heo [this message]
2007-04-11  6:42 ` [PATCH 04/12] libata: implement ata_host_alloc_pinfo() and ata_host_register() Tejun Heo
2007-04-11  6:42 ` [PATCH 03/12] libata: separate out ata_host_alloc() " Tejun Heo
2007-04-11  6:42 ` [PATCH 07/12] libata: add init helpers including ata_pci_prepare_native_host() Tejun Heo
2007-04-11  6:42 ` [PATCH 05/12] libata: convert legacy PCI host handling to new init model Tejun Heo
2007-04-11  6:42 ` [PATCH 11/12] libata: convert the remaining PATA drivers " Tejun Heo
2007-04-11  8:22   ` Alan Cox
2007-04-11  8:37     ` [PATCH 11/12 UPDATED] " Tejun Heo
2007-04-11  6:42 ` [PATCH 09/12] libata: convert ata_pci_init_native_mode() users " Tejun Heo
2007-04-11  6:42 ` [PATCH 12/12] libata: kill probe_ent and related helpers Tejun Heo
2007-04-11  6:42 ` [PATCH 08/12] libata: convert drivers with combined SATA/PATA ports to new init model Tejun Heo
2007-04-11  6:42 ` [PATCH 06/12] libata: convert native PCI host handling " Tejun Heo
2007-04-11  6:42 ` [PATCH 10/12] libata: convert the remaining SATA drivers " Tejun Heo
  -- strict thread matches above, loose matches on Subject: below --
2007-03-09 11:15 [PATCHSET] libata: implement new initialization model, take #3 Tejun Heo
2007-03-09 11:15 ` [PATCH 02/12] libata: separate out ata_host_start() Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11762737243666-git-send-email-htejun@gmail.com \
    --to=htejun@gmail.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=brking@linux.vnet.ibm.com \
    --cc=jeff@garzik.org \
    --cc=linux-ide@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).