Skip to content

Commit

Permalink
libata-link: implement and use link/device iterators
Browse files Browse the repository at this point in the history
Multiple links and different number of devices per link should be
considered to iterate over links and devices.  This patch implements
and uses link and device iterators - ata_port_for_each_link() and
ata_link_for_each_dev() - and ata_link_max_devices().

This change makes a lot of functions iterate over only possible
devices instead of from dev 0 to dev ATA_MAX_DEVICES.  All such
changes have been examined and nothing should be broken.

While at it, add a separating comment before device helpers to
distinguish them better from link helpers and others.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
htejun authored and Jeff Garzik committed Oct 12, 2007
1 parent 9af5c9c commit f58229f
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 148 deletions.
7 changes: 3 additions & 4 deletions drivers/ata/ata_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,20 @@
static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int dma_enabled = 0;
int i;
struct ata_device *dev;

/* Bits 5 and 6 indicate if DMA is active on master/slave */
if (ap->ioaddr.bmdma_addr)
dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);

for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->link.device[i];
ata_link_for_each_dev(dev, &ap->link) {
if (ata_dev_enabled(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->dma_mode = XFER_MW_DMA_0;
/* We do need the right mode information for DMA or PIO
and this comes from the current configuration flags */
if (dma_enabled & (1 << (5 + i))) {
if (dma_enabled & (1 << (5 + dev->devno))) {
ata_id_to_dma_mode(dev, XFER_MW_DMA_0);
dev->flags &= ~ATA_DFLAG_PIO;
} else {
Expand Down
6 changes: 3 additions & 3 deletions drivers/ata/libata-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ int ata_acpi_on_suspend(struct ata_port *ap)
*/
void ata_acpi_on_resume(struct ata_port *ap)
{
int i;
struct ata_device *dev;

if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) {
BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
Expand All @@ -519,8 +519,8 @@ void ata_acpi_on_resume(struct ata_port *ap)
}

/* schedule _GTF */
for (i = 0; i < ATA_MAX_DEVICES; i++)
ap->link.device[i].flags |= ATA_DFLAG_ACPI_PENDING;
ata_link_for_each_dev(dev, &ap->link)
dev->flags |= ATA_DFLAG_ACPI_PENDING;
}

/**
Expand Down
58 changes: 24 additions & 34 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2105,21 +2105,19 @@ int ata_bus_probe(struct ata_port *ap)
{
unsigned int classes[ATA_MAX_DEVICES];
int tries[ATA_MAX_DEVICES];
int i, rc;
int rc;
struct ata_device *dev;

ata_port_probe(ap);

for (i = 0; i < ATA_MAX_DEVICES; i++)
tries[i] = ATA_PROBE_MAX_TRIES;
ata_link_for_each_dev(dev, &ap->link)
tries[dev->devno] = ATA_PROBE_MAX_TRIES;

retry:
/* reset and determine device classes */
ap->ops->phy_reset(ap);

for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->link.device[i];

ata_link_for_each_dev(dev, &ap->link) {
if (!(ap->flags & ATA_FLAG_DISABLED) &&
dev->class != ATA_DEV_UNKNOWN)
classes[dev->devno] = dev->class;
Expand All @@ -2134,18 +2132,16 @@ int ata_bus_probe(struct ata_port *ap)
/* after the reset the device state is PIO 0 and the controller
state is undefined. Record the mode */

for (i = 0; i < ATA_MAX_DEVICES; i++)
ap->link.device[i].pio_mode = XFER_PIO_0;
ata_link_for_each_dev(dev, &ap->link)
dev->pio_mode = XFER_PIO_0;

/* read IDENTIFY page and configure devices. We have to do the identify
specific sequence bass-ackwards so that PDIAG- is released by
the slave device */

for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) {
dev = &ap->link.device[i];

if (tries[i])
dev->class = classes[i];
ata_link_for_each_dev(dev, &ap->link) {
if (tries[dev->devno])
dev->class = classes[dev->devno];

if (!ata_dev_enabled(dev))
continue;
Expand All @@ -2163,8 +2159,7 @@ int ata_bus_probe(struct ata_port *ap)
/* 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 */

for(i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->link.device[i];
ata_link_for_each_dev(dev, &ap->link) {
if (!ata_dev_enabled(dev))
continue;

Expand All @@ -2180,8 +2175,8 @@ int ata_bus_probe(struct ata_port *ap)
if (rc)
goto fail;

for (i = 0; i < ATA_MAX_DEVICES; i++)
if (ata_dev_enabled(&ap->link.device[i]))
ata_link_for_each_dev(dev, &ap->link)
if (ata_dev_enabled(dev))
return 0;

/* no device present, disable port */
Expand Down Expand Up @@ -2803,16 +2798,14 @@ static int ata_dev_set_mode(struct ata_device *dev)

int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
{
struct ata_link *link = &ap->link;
struct ata_device *dev;
int i, rc = 0, used_dma = 0, found = 0;

int rc = 0, used_dma = 0, found = 0;

/* step 1: calculate xfer_mask */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
ata_link_for_each_dev(dev, link) {
unsigned int pio_mask, dma_mask;

dev = &ap->link.device[i];

if (!ata_dev_enabled(dev))
continue;

Expand All @@ -2831,8 +2824,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
goto out;

/* step 2: always set host PIO timings */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->link.device[i];
ata_link_for_each_dev(dev, link) {
if (!ata_dev_enabled(dev))
continue;

Expand All @@ -2849,9 +2841,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
}

/* step 3: set host DMA timings */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->link.device[i];

ata_link_for_each_dev(dev, link) {
if (!ata_dev_enabled(dev) || !dev->dma_mode)
continue;

Expand All @@ -2862,9 +2852,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
}

/* step 4: update devices' xfer mode */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->link.device[i];

ata_link_for_each_dev(dev, link) {
/* don't update suspended devices' xfer mode */
if (!ata_dev_enabled(dev))
continue;
Expand Down Expand Up @@ -6113,6 +6101,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)

ap->link.ap = ap;

/* can't use iterator, ap isn't initialized yet */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->link.device[i];
dev->link = &ap->link;
Expand Down Expand Up @@ -6453,7 +6442,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
/* kick EH for boot probing */
spin_lock_irqsave(ap->lock, flags);

ehi->probe_mask = (1 << ATA_MAX_DEVICES) - 1;
ehi->probe_mask =
(1 << ata_link_max_devices(&ap->link)) - 1;
ehi->action |= ATA_EH_SOFTRESET;
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;

Expand Down Expand Up @@ -6551,7 +6541,7 @@ int ata_host_activate(struct ata_host *host, int irq,
void ata_port_detach(struct ata_port *ap)
{
unsigned long flags;
int i;
struct ata_device *dev;

if (!ap->ops->error_handler)
goto skip_eh;
Expand All @@ -6568,8 +6558,8 @@ void ata_port_detach(struct ata_port *ap)
*/
spin_lock_irqsave(ap->lock, flags);

for (i = 0; i < ATA_MAX_DEVICES; i++)
ata_dev_disable(&ap->link.device[i]);
ata_link_for_each_dev(dev, &ap->link)
ata_dev_disable(dev);

spin_unlock_irqrestore(ap->lock, flags);

Expand Down
Loading

0 comments on commit f58229f

Please sign in to comment.