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

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

libata: beef up iterators



There currently are the following looping constructs.

* __ata_port_for_each_link() for all available links
* ata_port_for_each_link() for edge links
* ata_link_for_each_dev() for all devices
* ata_link_for_each_dev_reverse() for all devices in reverse order

Now there's a need for looping construct which is similar to
__ata_port_for_each_link() but iterates over PMP links before the host
link.  Instead of adding another one with long name, do the following
cleanup.

* Implement and export ata_link_next() and ata_dev_next() which take
  @mode parameter and can be used to build custom loop.
* Implement ata_for_each_link() and ata_for_each_dev() which take
  looping mode explicitly.

The following iteration modes are implemented.

* ATA_LITER_EDGE		: loop over edge links
* ATA_LITER_HOST_FIRST		: loop over all links, host link first
* ATA_LITER_PMP_FIRST		: loop over all links, PMP links first

* ATA_DITER_ENABLED		: loop over enabled devices
* ATA_DITER_ENABLED_REVERSE	: loop over enabled devices in reverse order
* ATA_DITER_ALL			: loop over all devices
* ATA_DITER_ALL_REVERSE		: loop over all devices in reverse order

This change removes exlicit device enabledness checks from many loops
and makes it clear which ones are iterated over in which direction.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 3c92ec8a
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1119,14 +1119,14 @@ static void ahci_start_port(struct ata_port *ap)

	/* turn on LEDs */
	if (ap->flags & ATA_FLAG_EM) {
		ata_port_for_each_link(link, ap) {
		ata_for_each_link(link, ap, EDGE) {
			emp = &pp->em_priv[link->pmp];
			ahci_transmit_led_message(ap, emp->led_state, 4);
		}
	}

	if (ap->flags & ATA_FLAG_SW_ACTIVITY)
		ata_port_for_each_link(link, ap)
		ata_for_each_link(link, ap, EDGE)
			ahci_init_sw_activity(link);

}
@@ -1361,7 +1361,7 @@ static ssize_t ahci_led_show(struct ata_port *ap, char *buf)
	struct ahci_em_priv *emp;
	int rc = 0;

	ata_port_for_each_link(link, ap) {
	ata_for_each_link(link, ap, EDGE) {
		emp = &pp->em_priv[link->pmp];
		rc += sprintf(buf, "%lx\n", emp->led_state);
	}
@@ -1941,7 +1941,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
	u32 serror;

	/* determine active link */
	ata_port_for_each_link(link, ap)
	ata_for_each_link(link, ap, EDGE)
		if (ata_link_active(link))
			break;
	if (!link)
+1 −4
Original line number Diff line number Diff line
@@ -57,10 +57,7 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused)
	if (pdev->vendor == PCI_VENDOR_ID_CENATEK)
		dma_enabled = 0xFF;

	ata_link_for_each_dev(dev, link) {
		if (!ata_dev_enabled(dev))
			continue;

	ata_for_each_dev(dev, link, ENABLED) {
		/* We don't really care */
		dev->pio_mode = XFER_PIO_0;
		dev->dma_mode = XFER_MW_DMA_0;
+8 −11
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap)

		ap->link.device->acpi_handle = NULL;

		ata_port_for_each_link(link, ap) {
		ata_for_each_link(link, ap, EDGE) {
			acpi_integer adr = SATA_ADR(ap->port_no, link->pmp);

			link->device->acpi_handle =
@@ -129,8 +129,8 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
		struct ata_link *tlink;
		struct ata_device *tdev;

		ata_port_for_each_link(tlink, ap)
			ata_link_for_each_dev(tdev, tlink)
		ata_for_each_link(tlink, ap, EDGE)
			ata_for_each_dev(tdev, tlink, ALL)
				tdev->flags |= ATA_DFLAG_DETACH;
	}

@@ -588,12 +588,9 @@ int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm)
{
	struct ata_device *dev;

	ata_link_for_each_dev(dev, &ap->link) {
	ata_for_each_dev(dev, &ap->link, ENABLED) {
		unsigned long xfer_mask, udma_mask;

		if (!ata_dev_enabled(dev))
			continue;

		xfer_mask = ata_acpi_gtm_xfermask(dev, gtm);
		ata_unpack_xfermask(xfer_mask, NULL, NULL, &udma_mask);

@@ -893,7 +890,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
		 * use values set by _STM.  Cache _GTF result and
		 * schedule _GTF.
		 */
		ata_link_for_each_dev(dev, &ap->link) {
		ata_for_each_dev(dev, &ap->link, ALL) {
			ata_acpi_clear_gtf(dev);
			if (ata_dev_enabled(dev) &&
			    ata_dev_get_GTF(dev, NULL) >= 0)
@@ -904,7 +901,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
		 * there's no reason to evaluate IDE _GTF early
		 * without _STM.  Clear cache and schedule _GTF.
		 */
		ata_link_for_each_dev(dev, &ap->link) {
		ata_for_each_dev(dev, &ap->link, ALL) {
			ata_acpi_clear_gtf(dev);
			if (ata_dev_enabled(dev))
				dev->flags |= ATA_DFLAG_ACPI_PENDING;
@@ -932,8 +929,8 @@ void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
	if (state.event == PM_EVENT_ON)
		acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0);

	ata_link_for_each_dev(dev, &ap->link) {
		if (dev->acpi_handle && ata_dev_enabled(dev))
	ata_for_each_dev(dev, &ap->link, ENABLED) {
		if (dev->acpi_handle)
			acpi_bus_set_power(dev->acpi_handle,
				state.event == PM_EVENT_ON ?
					ACPI_STATE_D0 : ACPI_STATE_D3);
+122 −61
Original line number Diff line number Diff line
@@ -163,42 +163,118 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);


/*
 * Iterator helpers.  Don't use directly.
/**
 *	ata_link_next - link iteration helper
 *	@link: the previous link, NULL to start
 *	@ap: ATA port containing links to iterate
 *	@mode: iteration mode, one of ATA_LITER_*
 *
 *	LOCKING:
 *	Host lock or EH context.
 *
 *	RETURNS:
 *	Pointer to the next link.
 */
struct ata_link *__ata_port_next_link(struct ata_port *ap,
				      struct ata_link *link, bool dev_only)
struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap,
			       enum ata_link_iter_mode mode)
{
	BUG_ON(mode != ATA_LITER_EDGE &&
	       mode != ATA_LITER_PMP_FIRST && mode != ATA_LITER_HOST_FIRST);

	/* NULL link indicates start of iteration */
	if (!link) {
		if (dev_only && sata_pmp_attached(ap))
	if (!link)
		switch (mode) {
		case ATA_LITER_EDGE:
		case ATA_LITER_PMP_FIRST:
			if (sata_pmp_attached(ap))
				return ap->pmp_link;
			/* fall through */
		case ATA_LITER_HOST_FIRST:
			return &ap->link;
		}

	/* we just iterated over the host master link, what's next? */
	if (link == &ap->link) {
		if (!sata_pmp_attached(ap)) {
			if (unlikely(ap->slave_link) && !dev_only)
	/* we just iterated over the host link, what's next? */
	if (link == &ap->link)
		switch (mode) {
		case ATA_LITER_HOST_FIRST:
			if (sata_pmp_attached(ap))
				return ap->pmp_link;
			/* fall through */
		case ATA_LITER_PMP_FIRST:
			if (unlikely(ap->slave_link))
				return ap->slave_link;
			/* fall through */
		case ATA_LITER_EDGE:
			return NULL;
		}
		return ap->pmp_link;
	}

	/* slave_link excludes PMP */
	if (unlikely(link == ap->slave_link))
		return NULL;

	/* iterate to the next PMP link */
	/* we were over a PMP link */
	if (++link < ap->pmp_link + ap->nr_pmp_links)
		return link;

	if (mode == ATA_LITER_PMP_FIRST)
		return &ap->link;

	return NULL;
}

/**
 *	ata_dev_next - device iteration helper
 *	@dev: the previous device, NULL to start
 *	@link: ATA link containing devices to iterate
 *	@mode: iteration mode, one of ATA_DITER_*
 *
 *	LOCKING:
 *	Host lock or EH context.
 *
 *	RETURNS:
 *	Pointer to the next device.
 */
struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link,
				enum ata_dev_iter_mode mode)
{
	BUG_ON(mode != ATA_DITER_ENABLED && mode != ATA_DITER_ENABLED_REVERSE &&
	       mode != ATA_DITER_ALL && mode != ATA_DITER_ALL_REVERSE);

	/* NULL dev indicates start of iteration */
	if (!dev)
		switch (mode) {
		case ATA_DITER_ENABLED:
		case ATA_DITER_ALL:
			dev = link->device;
			goto check;
		case ATA_DITER_ENABLED_REVERSE:
		case ATA_DITER_ALL_REVERSE:
			dev = link->device + ata_link_max_devices(link) - 1;
			goto check;
		}

 next:
	/* move to the next one */
	switch (mode) {
	case ATA_DITER_ENABLED:
	case ATA_DITER_ALL:
		if (++dev < link->device + ata_link_max_devices(link))
			goto check;
		return NULL;
	case ATA_DITER_ENABLED_REVERSE:
	case ATA_DITER_ALL_REVERSE:
		if (--dev >= link->device)
			goto check;
		return NULL;
	}

 check:
	if ((mode == ATA_DITER_ENABLED || mode == ATA_DITER_ENABLED_REVERSE) &&
	    !ata_dev_enabled(dev))
		goto next;
	return dev;
}

/**
 *	ata_dev_phys_link - find physical link for a device
 *	@dev: ATA device to look up physical link for
@@ -1107,8 +1183,8 @@ static void ata_lpm_enable(struct ata_host *host)

	for (i = 0; i < host->n_ports; i++) {
		ap = host->ports[i];
		ata_port_for_each_link(link, ap) {
			ata_link_for_each_dev(dev, link)
		ata_for_each_link(link, ap, EDGE) {
			ata_for_each_dev(dev, link, ALL)
				ata_dev_disable_pm(dev);
		}
	}
@@ -2594,11 +2670,11 @@ int ata_bus_probe(struct ata_port *ap)

	ata_port_probe(ap);

	ata_link_for_each_dev(dev, &ap->link)
	ata_for_each_dev(dev, &ap->link, ALL)
		tries[dev->devno] = ATA_PROBE_MAX_TRIES;

 retry:
	ata_link_for_each_dev(dev, &ap->link) {
	ata_for_each_dev(dev, &ap->link, ALL) {
		/* If we issue an SRST then an ATA drive (not ATAPI)
		 * may change configuration and be in PIO0 timing. If
		 * we do a hard reset (or are coming from power on)
@@ -2620,7 +2696,7 @@ int ata_bus_probe(struct ata_port *ap)
	/* reset and determine device classes */
	ap->ops->phy_reset(ap);

	ata_link_for_each_dev(dev, &ap->link) {
	ata_for_each_dev(dev, &ap->link, ALL) {
		if (!(ap->flags & ATA_FLAG_DISABLED) &&
		    dev->class != ATA_DEV_UNKNOWN)
			classes[dev->devno] = dev->class;
@@ -2636,7 +2712,7 @@ int ata_bus_probe(struct ata_port *ap)
	   specific sequence bass-ackwards so that PDIAG- is released by
	   the slave device */

	ata_link_for_each_dev_reverse(dev, &ap->link) {
	ata_for_each_dev(dev, &ap->link, ALL_REVERSE) {
		if (tries[dev->devno])
			dev->class = classes[dev->devno];

@@ -2653,24 +2729,19 @@ int ata_bus_probe(struct ata_port *ap)
	if (ap->ops->cable_detect)
		ap->cbl = ap->ops->cable_detect(ap);

	/* We may have SATA bridge glue hiding here irrespective of the
	   reported cable types and sensed types */
	ata_link_for_each_dev(dev, &ap->link) {
		if (!ata_dev_enabled(dev))
			continue;
		/* SATA drives indicate we have a bridge. We don't know which
		   end of the link the bridge is which is a problem */
	/* We may have SATA bridge glue hiding here irrespective of
	 * the reported cable types and sensed types.  When SATA
	 * drives indicate we have a bridge, we don't know which end
	 * of the link the bridge is which is a problem.
	 */
	ata_for_each_dev(dev, &ap->link, ENABLED)
		if (ata_id_is_sata(dev->id))
			ap->cbl = ATA_CBL_SATA;
	}

	/* After the identify sequence we can now set up the devices. We do
	   this in the normal order so that the user doesn't get confused */

	ata_link_for_each_dev(dev, &ap->link) {
		if (!ata_dev_enabled(dev))
			continue;

	ata_for_each_dev(dev, &ap->link, ENABLED) {
		ap->link.eh_context.i.flags |= ATA_EHI_PRINTINFO;
		rc = ata_dev_configure(dev);
		ap->link.eh_context.i.flags &= ~ATA_EHI_PRINTINFO;
@@ -2683,8 +2754,7 @@ int ata_bus_probe(struct ata_port *ap)
	if (rc)
		goto fail;

	ata_link_for_each_dev(dev, &ap->link)
		if (ata_dev_enabled(dev))
	ata_for_each_dev(dev, &ap->link, ENABLED)
		return 0;

	/* no device present, disable port */
@@ -3331,13 +3401,10 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
	int rc = 0, used_dma = 0, found = 0;

	/* step 1: calculate xfer_mask */
	ata_link_for_each_dev(dev, link) {
	ata_for_each_dev(dev, link, ENABLED) {
		unsigned long pio_mask, dma_mask;
		unsigned int mode_mask;

		if (!ata_dev_enabled(dev))
			continue;

		mode_mask = ATA_DMA_MASK_ATA;
		if (dev->class == ATA_DEV_ATAPI)
			mode_mask = ATA_DMA_MASK_ATAPI;
@@ -3366,10 +3433,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
		goto out;

	/* step 2: always set host PIO timings */
	ata_link_for_each_dev(dev, link) {
		if (!ata_dev_enabled(dev))
			continue;

	ata_for_each_dev(dev, link, ENABLED) {
		if (dev->pio_mode == 0xff) {
			ata_dev_printk(dev, KERN_WARNING, "no PIO support\n");
			rc = -EINVAL;
@@ -3383,8 +3447,8 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
	}

	/* step 3: set host DMA timings */
	ata_link_for_each_dev(dev, link) {
		if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev))
	ata_for_each_dev(dev, link, ENABLED) {
		if (!ata_dma_enabled(dev))
			continue;

		dev->xfer_mode = dev->dma_mode;
@@ -3394,11 +3458,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
	}

	/* step 4: update devices' xfer mode */
	ata_link_for_each_dev(dev, link) {
		/* don't update suspended devices' xfer mode */
		if (!ata_dev_enabled(dev))
			continue;

	ata_for_each_dev(dev, link, ENABLED) {
		rc = ata_dev_set_mode(dev);
		if (rc)
			goto out;
@@ -4263,9 +4323,9 @@ static int cable_is_40wire(struct ata_port *ap)
	 * - if you have a non detect capable drive you don't want it
	 *   to colour the choice
	 */
	ata_port_for_each_link(link, ap) {
		ata_link_for_each_dev(dev, link) {
			if (ata_dev_enabled(dev) && !ata_is_40wire(dev))
	ata_for_each_link(link, ap, EDGE) {
		ata_for_each_dev(dev, link, ENABLED) {
			if (!ata_is_40wire(dev))
				return 0;
		}
	}
@@ -5218,7 +5278,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
		}

		ap->pflags |= ATA_PFLAG_PM_PENDING;
		__ata_port_for_each_link(link, ap) {
		ata_for_each_link(link, ap, HOST_FIRST) {
			link->eh_info.action |= action;
			link->eh_info.flags |= ehi_flags;
		}
@@ -6063,9 +6123,9 @@ static void ata_port_detach(struct ata_port *ap)
	/* EH is now guaranteed to see UNLOADING - EH context belongs
	 * to us.  Restore SControl and disable all existing devices.
	 */
	__ata_port_for_each_link(link, ap) {
	ata_for_each_link(link, ap, HOST_FIRST) {
		sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0);
		ata_link_for_each_dev(dev, link)
		ata_for_each_dev(dev, link, ALL)
			ata_dev_disable(dev);
	}

@@ -6528,7 +6588,8 @@ EXPORT_SYMBOL_GPL(ata_base_port_ops);
EXPORT_SYMBOL_GPL(sata_port_ops);
EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
EXPORT_SYMBOL_GPL(ata_dummy_port_info);
EXPORT_SYMBOL_GPL(__ata_port_next_link);
EXPORT_SYMBOL_GPL(ata_link_next);
EXPORT_SYMBOL_GPL(ata_dev_next);
EXPORT_SYMBOL_GPL(ata_std_bios_param);
EXPORT_SYMBOL_GPL(ata_host_init);
EXPORT_SYMBOL_GPL(ata_host_alloc);
+37 −47
Original line number Diff line number Diff line
@@ -422,7 +422,7 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,

	if (!dev) {
		ehi->action &= ~action;
		ata_link_for_each_dev(tdev, link)
		ata_for_each_dev(tdev, link, ALL)
			ehi->dev_action[tdev->devno] &= ~action;
	} else {
		/* doesn't make sense for port-wide EH actions */
@@ -430,7 +430,7 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,

		/* break ehi->action into ehi->dev_action */
		if (ehi->action & action) {
			ata_link_for_each_dev(tdev, link)
			ata_for_each_dev(tdev, link, ALL)
				ehi->dev_action[tdev->devno] |=
					ehi->action & action;
			ehi->action &= ~action;
@@ -592,7 +592,7 @@ void ata_scsi_error(struct Scsi_Host *host)
		/* fetch & clear EH info */
		spin_lock_irqsave(ap->lock, flags);

		__ata_port_for_each_link(link, ap) {
		ata_for_each_link(link, ap, HOST_FIRST) {
			struct ata_eh_context *ehc = &link->eh_context;
			struct ata_device *dev;

@@ -600,12 +600,9 @@ void ata_scsi_error(struct Scsi_Host *host)
			link->eh_context.i = link->eh_info;
			memset(&link->eh_info, 0, sizeof(link->eh_info));

			ata_link_for_each_dev(dev, link) {
			ata_for_each_dev(dev, link, ENABLED) {
				int devno = dev->devno;

				if (!ata_dev_enabled(dev))
					continue;

				ehc->saved_xfer_mode[devno] = dev->xfer_mode;
				if (ata_ncq_enabled(dev))
					ehc->saved_ncq_enabled |= 1 << devno;
@@ -644,7 +641,7 @@ void ata_scsi_error(struct Scsi_Host *host)
		}

		/* this run is complete, make sure EH info is clear */
		__ata_port_for_each_link(link, ap)
		ata_for_each_link(link, ap, HOST_FIRST)
			memset(&link->eh_info, 0, sizeof(link->eh_info));

		/* Clear host_eh_scheduled while holding ap->lock such
@@ -1025,7 +1022,7 @@ int sata_async_notification(struct ata_port *ap)
		struct ata_link *link;

		/* check and notify ATAPI AN */
		ata_port_for_each_link(link, ap) {
		ata_for_each_link(link, ap, EDGE) {
			if (!(sntf & (1 << link->pmp)))
				continue;

@@ -2005,7 +2002,7 @@ void ata_eh_autopsy(struct ata_port *ap)
{
	struct ata_link *link;

	ata_port_for_each_link(link, ap)
	ata_for_each_link(link, ap, EDGE)
		ata_eh_link_autopsy(link);

	/* Handle the frigging slave link.  Autopsy is done similarly
@@ -2219,7 +2216,7 @@ void ata_eh_report(struct ata_port *ap)
{
	struct ata_link *link;

	__ata_port_for_each_link(link, ap)
	ata_for_each_link(link, ap, HOST_FIRST)
		ata_eh_link_report(link);
}

@@ -2230,7 +2227,7 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
	struct ata_device *dev;

	if (clear_classes)
		ata_link_for_each_dev(dev, link)
		ata_for_each_dev(dev, link, ALL)
			classes[dev->devno] = ATA_DEV_UNKNOWN;

	return reset(link, classes, deadline);
@@ -2294,7 +2291,7 @@ int ata_eh_reset(struct ata_link *link, int classify,

	ata_eh_about_to_do(link, NULL, ATA_EH_RESET);

	ata_link_for_each_dev(dev, link) {
	ata_for_each_dev(dev, link, ALL) {
		/* If we issue an SRST then an ATA drive (not ATAPI)
		 * may change configuration and be in PIO0 timing. If
		 * we do a hard reset (or are coming from power on)
@@ -2355,7 +2352,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
						"port disabled. ignoring.\n");
				ehc->i.action &= ~ATA_EH_RESET;

				ata_link_for_each_dev(dev, link)
				ata_for_each_dev(dev, link, ALL)
					classes[dev->devno] = ATA_DEV_NONE;

				rc = 0;
@@ -2369,7 +2366,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
		 * bang classes and return.
		 */
		if (reset && !(ehc->i.action & ATA_EH_RESET)) {
			ata_link_for_each_dev(dev, link)
			ata_for_each_dev(dev, link, ALL)
				classes[dev->devno] = ATA_DEV_NONE;
			rc = 0;
			goto out;
@@ -2454,7 +2451,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
	/*
	 * Post-reset processing
	 */
	ata_link_for_each_dev(dev, link) {
	ata_for_each_dev(dev, link, ALL) {
		/* After the reset, the device state is PIO 0 and the
		 * controller state is undefined.  Reset also wakes up
		 * drives from sleeping mode.
@@ -2510,7 +2507,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
	 * can be reliably detected and retried.
	 */
	nr_unknown = 0;
	ata_link_for_each_dev(dev, link) {
	ata_for_each_dev(dev, link, ALL) {
		/* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
		if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
			classes[dev->devno] = ATA_DEV_NONE;
@@ -2619,8 +2616,8 @@ static inline void ata_eh_pull_park_action(struct ata_port *ap)

	spin_lock_irqsave(ap->lock, flags);
	INIT_COMPLETION(ap->park_req_pending);
	ata_port_for_each_link(link, ap) {
		ata_link_for_each_dev(dev, link) {
	ata_for_each_link(link, ap, EDGE) {
		ata_for_each_dev(dev, link, ALL) {
			struct ata_eh_info *ehi = &link->eh_info;

			link->eh_context.i.dev_action[dev->devno] |=
@@ -2675,7 +2672,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
	 * be done backwards such that PDIAG- is released by the slave
	 * device before the master device is identified.
	 */
	ata_link_for_each_dev_reverse(dev, link) {
	ata_for_each_dev(dev, link, ALL_REVERSE) {
		unsigned int action = ata_eh_dev_action(dev);
		unsigned int readid_flags = 0;

@@ -2744,7 +2741,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
	/* Configure new devices forward such that user doesn't see
	 * device detection messages backwards.
	 */
	ata_link_for_each_dev(dev, link) {
	ata_for_each_dev(dev, link, ALL) {
		if (!(new_mask & (1 << dev->devno)) ||
		    dev->class == ATA_DEV_PMP)
			continue;
@@ -2793,10 +2790,7 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
	int rc;

	/* if data transfer is verified, clear DUBIOUS_XFER on ering top */
	ata_link_for_each_dev(dev, link) {
		if (!ata_dev_enabled(dev))
			continue;

	ata_for_each_dev(dev, link, ENABLED) {
		if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) {
			struct ata_ering_entry *ent;

@@ -2813,14 +2807,11 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
		rc = ata_do_set_mode(link, r_failed_dev);

	/* if transfer mode has changed, set DUBIOUS_XFER on device */
	ata_link_for_each_dev(dev, link) {
	ata_for_each_dev(dev, link, ENABLED) {
		struct ata_eh_context *ehc = &link->eh_context;
		u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno];
		u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno));

		if (!ata_dev_enabled(dev))
			continue;

		if (dev->xfer_mode != saved_xfer_mode ||
		    ata_ncq_enabled(dev) != saved_ncq)
			dev->flags |= ATA_DFLAG_DUBIOUS_XFER;
@@ -2881,8 +2872,7 @@ static int ata_link_nr_enabled(struct ata_link *link)
	struct ata_device *dev;
	int cnt = 0;

	ata_link_for_each_dev(dev, link)
		if (ata_dev_enabled(dev))
	ata_for_each_dev(dev, link, ENABLED)
		cnt++;
	return cnt;
}
@@ -2892,7 +2882,7 @@ static int ata_link_nr_vacant(struct ata_link *link)
	struct ata_device *dev;
	int cnt = 0;

	ata_link_for_each_dev(dev, link)
	ata_for_each_dev(dev, link, ALL)
		if (dev->class == ATA_DEV_UNKNOWN)
			cnt++;
	return cnt;
@@ -2918,7 +2908,7 @@ static int ata_eh_skip_recovery(struct ata_link *link)
		return 0;

	/* skip if class codes for all vacant slots are ATA_DEV_NONE */
	ata_link_for_each_dev(dev, link) {
	ata_for_each_dev(dev, link, ALL) {
		if (dev->class == ATA_DEV_UNKNOWN &&
		    ehc->classes[dev->devno] != ATA_DEV_NONE)
			return 0;
@@ -3026,7 +3016,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
	DPRINTK("ENTER\n");

	/* prep for recovery */
	ata_port_for_each_link(link, ap) {
	ata_for_each_link(link, ap, EDGE) {
		struct ata_eh_context *ehc = &link->eh_context;

		/* re-enable link? */
@@ -3038,7 +3028,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
			ata_eh_done(link, NULL, ATA_EH_ENABLE_LINK);
		}

		ata_link_for_each_dev(dev, link) {
		ata_for_each_dev(dev, link, ALL) {
			if (link->flags & ATA_LFLAG_NO_RETRY)
				ehc->tries[dev->devno] = 1;
			else
@@ -3068,19 +3058,19 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
		goto out;

	/* prep for EH */
	ata_port_for_each_link(link, ap) {
	ata_for_each_link(link, ap, EDGE) {
		struct ata_eh_context *ehc = &link->eh_context;

		/* skip EH if possible. */
		if (ata_eh_skip_recovery(link))
			ehc->i.action = 0;

		ata_link_for_each_dev(dev, link)
		ata_for_each_dev(dev, link, ALL)
			ehc->classes[dev->devno] = ATA_DEV_UNKNOWN;
	}

	/* reset */
	ata_port_for_each_link(link, ap) {
	ata_for_each_link(link, ap, EDGE) {
		struct ata_eh_context *ehc = &link->eh_context;

		if (!(ehc->i.action & ATA_EH_RESET))
@@ -3105,8 +3095,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
		ata_eh_pull_park_action(ap);

		deadline = jiffies;
		ata_port_for_each_link(link, ap) {
			ata_link_for_each_dev(dev, link) {
		ata_for_each_link(link, ap, EDGE) {
			ata_for_each_dev(dev, link, ALL) {
				struct ata_eh_context *ehc = &link->eh_context;
				unsigned long tmp;

@@ -3134,8 +3124,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
		deadline = wait_for_completion_timeout(&ap->park_req_pending,
						       deadline - now);
	} while (deadline);
	ata_port_for_each_link(link, ap) {
		ata_link_for_each_dev(dev, link) {
	ata_for_each_link(link, ap, EDGE) {
		ata_for_each_dev(dev, link, ALL) {
			if (!(link->eh_context.unloaded_mask &
			      (1 << dev->devno)))
				continue;
@@ -3146,7 +3136,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
	}

	/* the rest */
	ata_port_for_each_link(link, ap) {
	ata_for_each_link(link, ap, EDGE) {
		struct ata_eh_context *ehc = &link->eh_context;

		/* revalidate existing devices and attach new ones */
@@ -3172,7 +3162,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
		 * disrupting the current users of the device.
		 */
		if (ehc->i.flags & ATA_EHI_DID_RESET) {
			ata_link_for_each_dev(dev, link) {
			ata_for_each_dev(dev, link, ALL) {
				if (dev->class != ATA_DEV_ATAPI)
					continue;
				rc = atapi_eh_clear_ua(dev);
@@ -3183,7 +3173,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,

		/* configure link power saving */
		if (ehc->i.action & ATA_EH_LPM)
			ata_link_for_each_dev(dev, link)
			ata_for_each_dev(dev, link, ALL)
				ata_dev_enable_pm(dev, ap->pm_policy);

		/* this link is okay now */
@@ -3288,7 +3278,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
	rc = ata_eh_recover(ap, prereset, softreset, hardreset, postreset,
			    NULL);
	if (rc) {
		ata_link_for_each_dev(dev, &ap->link)
		ata_for_each_dev(dev, &ap->link, ALL)
			ata_dev_disable(dev);
	}

Loading