From: Tejun Heo <htejun@gmail.com>
To: jgarzik@pobox.com, alan@lxorguk.ukuu.org.uk, mlord@pobox.com,
albertcc@tw.ibm.com, uchang@tw.ibm.com, forrest.zhao@intel.com,
brking@us.ibm.com, linux-ide@vger.kernel.org
Cc: Tejun Heo <htejun@gmail.com>
Subject: [PATCH 2/20] libata: implement ata_host_start/stop()
Date: Sat, 19 Aug 2006 17:59:30 +0900 [thread overview]
Message-ID: <1155977970528-git-send-email-htejun@gmail.com> (raw)
In-Reply-To: <11559778241753-git-send-email-htejun@gmail.com>
Implement [de-]init helpers ata_host_start/stop(). start() will start
all ports in the host while stop() does the opposite. These helpers
use ATA_PFLAG_STARTED to track whether a port is started or not and
thus can be called without side effect.
ata_host_stop() replaces half of ata_scsi_release() and the other half
is merged into ata_host_detach().
This patch introduces the follwing behavior changes.
* ->port_start/stop() can be omitted. This will be used to simplify
port initialization.
* ->port_disable() callback is reordered w.r.t. freeing IRQs. The
callback's roll and usefulness are questionable. All LLDs use
ata_port_disable() and libata-core directly calls ata_port_disable()
in several places. ->port_disable() invocation during port deinit
doesn't provide any feature. All are already done by EH. The
relocation doesn't cause any real behavior change.
This is a part of efforts to improve [de-]init paths and simplify
LLDs.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/ata/ahci.c | 9 +--
drivers/ata/libata-core.c | 129 +++++++++++++++++++++++++++++----------------
include/linux/libata.h | 5 +-
3 files changed, 91 insertions(+), 52 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 3f1106f..eb6ceb3 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1643,13 +1643,10 @@ static void ahci_remove_one (struct pci_
have_msi = hpriv->flags & AHCI_FLAG_MSI;
free_irq(host->irq, host);
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- ata_scsi_release(ap->scsi_host);
- scsi_host_put(ap->scsi_host);
- }
+ ata_host_stop(host);
+ for (i = 0; i < host->n_ports; i++)
+ scsi_host_put(host->ports[i]->scsi_host);
kfree(hpriv);
pci_iounmap(pdev, host->mmio_base);
kfree(host);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e8bbbaa..8472ec9 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5394,6 +5394,42 @@ void ata_host_init(struct ata_host *host
}
/**
+ * ata_host_start - start ports of an ATA host
+ * @host: ATA host to start ports for
+ *
+ * Start ports of @host. Port started status is recorded in
+ * ap->pflags, 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;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (ap->pflags & ATA_PFLAG_STARTED)
+ continue;
+
+ if (ap->ops->port_start) {
+ rc = ap->ops->port_start(ap);
+ if (rc)
+ return rc;
+ }
+
+ ap->pflags |= ATA_PFLAG_STARTED;
+ }
+
+ return 0;
+}
+
+/**
* ata_device_add - Register hardware device with ATA and SCSI layers
* @ent: Probe information describing hardware device to be registered
*
@@ -5451,14 +5487,6 @@ int ata_device_add(const struct ata_prob
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;
@@ -5476,6 +5504,16 @@ int ata_device_add(const struct ata_prob
ap->ioaddr.ctl_addr,
ap->ioaddr.bmdma_addr,
irq_line);
+ }
+
+ /* start ports */
+ rc = ata_host_start(host);
+ if (rc)
+ goto err_out;
+
+ /* freeze */
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
ata_chk_status(ap);
host->ops->irq_clear(ap);
@@ -5582,14 +5620,10 @@ int ata_device_add(const struct ata_prob
err_out_free_irq:
free_irq(ent->irq, host);
err_out:
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- if (ap) {
- ap->ops->port_stop(ap);
- scsi_host_put(ap->scsi_host);
- }
- }
+ ata_host_stop(host);
+ for (i = 0; i < host->n_ports; i++)
+ scsi_host_put(host->ports[i]->scsi_host);
kfree(host);
VPRINTK("EXIT, returning 0\n");
return 0;
@@ -5651,6 +5685,37 @@ void ata_port_detach(struct ata_port *ap
skip_eh:
/* remove the associated SCSI host */
scsi_remove_host(ap->scsi_host);
+
+ /* disable port */
+ ap->ops->port_disable(ap);
+}
+
+/**
+ * ata_host_stop - stop ports of an ATA host
+ * @host: ATA host to stop
+ *
+ * Stop ports of @host. Port started status is recorded in
+ * ap->pflags, so this functio can be called multiple times.
+ * Started ports are guranteed to be stopped only once.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ */
+void ata_host_stop(struct ata_host *host)
+{
+ int i;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (!ap || !(ap->pflags & ATA_PFLAG_STARTED))
+ continue;
+
+ if (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
+
+ ap->pflags &= ~ATA_PFLAG_STARTED;
+ }
}
/**
@@ -5675,11 +5740,11 @@ void ata_host_remove(struct ata_host *ho
if (host->irq2)
free_irq(host->irq2, host);
+ ata_host_stop(host);
+
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
- ata_scsi_release(ap->scsi_host);
-
if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -5699,33 +5764,6 @@ void ata_host_remove(struct ata_host *ho
kfree(host);
}
-/**
- * ata_scsi_release - SCSI layer callback hook for host unload
- * @host: libata host to be unloaded
- *
- * Performs all duties necessary to shut down a libata port...
- * Kill port kthread, disable port, and release resources.
- *
- * LOCKING:
- * Inherited from SCSI layer.
- *
- * RETURNS:
- * One.
- */
-
-int ata_scsi_release(struct Scsi_Host *shost)
-{
- struct ata_port *ap = ata_shost_to_port(shost);
-
- DPRINTK("ENTER\n");
-
- ap->ops->port_disable(ap);
- ap->ops->port_stop(ap);
-
- DPRINTK("EXIT\n");
- return 1;
-}
-
struct ata_probe_ent *
ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
{
@@ -6030,8 +6068,10 @@ 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_port_detach);
+EXPORT_SYMBOL_GPL(ata_host_stop);
EXPORT_SYMBOL_GPL(ata_host_remove);
EXPORT_SYMBOL_GPL(ata_sg_init);
EXPORT_SYMBOL_GPL(ata_sg_init_one);
@@ -6090,7 +6130,6 @@ 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_change_queue_depth);
-EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(sata_scr_valid);
EXPORT_SYMBOL_GPL(sata_scr_read);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 8fd8851..e098d32 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -184,6 +184,8 @@ enum {
ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
+ ATA_PFLAG_STARTED = (1 << 24), /* port has been started */
+
/* struct ata_queued_cmd flags */
ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */
ATA_QCFLAG_SG = (1 << 1), /* have s/g table? */
@@ -688,15 +690,16 @@ extern int ata_pci_device_suspend(struct
extern int ata_pci_device_resume(struct pci_dev *pdev);
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_port_detach(struct ata_port *ap);
+extern void ata_host_stop(struct ata_host *host);
extern void ata_host_init(struct ata_host *, struct device *,
unsigned long, const struct ata_port_operations *);
extern void ata_host_remove(struct ata_host *host);
extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
-extern int ata_scsi_release(struct Scsi_Host *host);
extern void ata_sas_port_destroy(struct ata_port *);
extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
struct ata_port_info *, struct Scsi_Host *);
--
1.4.1.1
next prev parent reply other threads:[~2006-08-19 8:59 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-19 8:57 [PATCHSET] libata: implement new initialization model w/ iomap support, take 2 Tejun Heo
2006-08-19 8:59 ` [PATCH 1/20] libata: kill ata_host_stop() Tejun Heo
2006-08-19 14:51 ` Jeff Garzik
2006-08-19 15:29 ` Tejun Heo
2006-09-19 4:46 ` Jeff Garzik
2006-09-19 4:50 ` Tejun Heo
2006-08-19 8:59 ` Tejun Heo [this message]
2006-08-19 8:59 ` [PATCH 4/20] libata: separate out ata_host_alloc() and ata_host_attach() Tejun Heo
2006-09-19 5:08 ` Jeff Garzik
2006-09-19 5:48 ` Tejun Heo
2006-08-19 8:59 ` [PATCH 7/20] libata: implement PCI ATA init helpers Tejun Heo
2006-09-19 5:29 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 6/20] libata: implement legacy " Tejun Heo
2006-09-19 5:26 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 5/20] libata: implement several LLD " Tejun Heo
2006-08-22 22:11 ` Brian King
2006-08-27 9:52 ` Tejun Heo
2006-08-30 21:16 ` Brian King
2006-09-19 5:16 ` Jeff Garzik
2006-09-19 5:57 ` Tejun Heo
2006-08-19 8:59 ` [PATCH 3/20] libata: implement ata_host_detach() and ata_host_free() Tejun Heo
2006-09-19 4:59 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 12/20] libata: kill old init helpers Tejun Heo
2006-08-19 8:59 ` [PATCH 11/20] libata: use remove_one() for deinit instead of ->host_stop() Tejun Heo
2006-09-19 5:42 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 8/20] libata: reimplement ata_pci_init_one() using new init helpers Tejun Heo
2006-09-19 5:32 ` Jeff Garzik
2006-09-19 6:04 ` Tejun Heo
2006-09-19 6:09 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 13/20] libata: kill unused ->host_stop() operation and related functions Tejun Heo
2006-09-19 5:42 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 10/20] libata: reimplement ata_pci_remove_one() using new PCI init helpers Tejun Heo
2006-08-19 8:59 ` [PATCH 17/20] libata: make ata_pci_acquire_resources() handle iomap Tejun Heo
2006-09-19 5:47 ` Jeff Garzik
2006-09-19 6:27 ` Tejun Heo
2006-09-19 6:32 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 14/20] libata: use LLD name where possible Tejun Heo
2006-09-19 5:43 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 15/20] libata: move ->irq_handler from port_ops to port_info Tejun Heo
2006-09-19 5:43 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 16/20] libata: make ata_host_alloc() take care of hpriv alloc/free Tejun Heo
2006-09-19 5:45 ` Jeff Garzik
2006-08-19 8:59 ` [PATCH 19/20] libata: kill unused ATA_FLAG_MMIO Tejun Heo
2006-08-19 8:59 ` [PATCH 20/20] libata: move scattered PCI ATA functions into liata-pci.c Tejun Heo
2006-09-19 5:50 ` Jeff Garzik
2006-08-22 22:10 ` [PATCHSET] libata: implement new initialization model w/ iomap support, take 2 Brian King
2006-08-27 10:12 ` Tejun Heo
2006-08-30 20:58 ` Brian King
2006-09-01 13:45 ` Tejun Heo
2006-09-07 13:22 ` Brian King
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=1155977970528-git-send-email-htejun@gmail.com \
--to=htejun@gmail.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=albertcc@tw.ibm.com \
--cc=brking@us.ibm.com \
--cc=forrest.zhao@intel.com \
--cc=jgarzik@pobox.com \
--cc=linux-ide@vger.kernel.org \
--cc=mlord@pobox.com \
--cc=uchang@tw.ibm.com \
/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).