Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ecef7253 authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

libata: separate out ata_host_start()



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: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 4911487a
Loading
Loading
Loading
Loading
+61 −13
Original line number Diff line number Diff line
@@ -5819,11 +5819,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++) {
@@ -5842,6 +5845,56 @@ static void ata_host_release(struct device *gendev, void *res)
	dev_set_drvdata(gendev, NULL);
}

/**
 *	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
@@ -5931,14 +5984,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;
@@ -5956,11 +6001,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);
@@ -6446,6 +6493,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);
+2 −0
Original line number Diff line number Diff line
@@ -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 *,