Commit 37deecb5 authored by Tejun Heo's avatar Tejun Heo

[PATCH] libata: implement per-dev xfermask

Implement per-dev xfermask.  libata used to determine xfermask
per-port - the fastest mode of the slowest device on the port.  This
patch enables per-dev xfermask.

Original patch is from Alan Cox <alan@redhat.com>.  The following
changes are made by me.

* simplex warning message is added
* remove disabled device handling code which is never invoked
  (originally for choosing port-wide lowest PIO mode)

Cc: Alan Cox <alan@redhat.com>
Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
parent 6d0500df
...@@ -3040,10 +3040,6 @@ static int ata_dma_blacklisted(const struct ata_device *dev) ...@@ -3040,10 +3040,6 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
* known limits including host controller limits, device * known limits including host controller limits, device
* blacklist, etc... * blacklist, etc...
* *
* FIXME: The current implementation limits all transfer modes to
* the fastest of the lowested device on the port. This is not
* required on most controllers.
*
* LOCKING: * LOCKING:
* None. * None.
*/ */
...@@ -3052,8 +3048,8 @@ static void ata_dev_xfermask(struct ata_device *dev) ...@@ -3052,8 +3048,8 @@ static void ata_dev_xfermask(struct ata_device *dev)
struct ata_port *ap = dev->ap; struct ata_port *ap = dev->ap;
struct ata_host_set *hs = ap->host_set; struct ata_host_set *hs = ap->host_set;
unsigned long xfer_mask; unsigned long xfer_mask;
int i;
/* controller modes available */
xfer_mask = ata_pack_xfermask(ap->pio_mask, xfer_mask = ata_pack_xfermask(ap->pio_mask,
ap->mwdma_mask, ap->udma_mask); ap->mwdma_mask, ap->udma_mask);
...@@ -3063,34 +3059,20 @@ static void ata_dev_xfermask(struct ata_device *dev) ...@@ -3063,34 +3059,20 @@ static void ata_dev_xfermask(struct ata_device *dev)
if (ap->cbl == ATA_CBL_PATA40) if (ap->cbl == ATA_CBL_PATA40)
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
/* FIXME: Use port-wide xfermask for now */ xfer_mask &= ata_pack_xfermask(dev->pio_mask,
for (i = 0; i < ATA_MAX_DEVICES; i++) { dev->mwdma_mask, dev->udma_mask);
struct ata_device *d = &ap->device[i]; xfer_mask &= ata_id_xfermask(dev->id);
if (ata_dev_absent(d))
continue;
if (ata_dev_disabled(d)) { if (ata_dma_blacklisted(dev)) {
/* to avoid violating device selection timing */
xfer_mask &= ata_pack_xfermask(d->pio_mask,
UINT_MAX, UINT_MAX);
continue;
}
xfer_mask &= ata_pack_xfermask(d->pio_mask,
d->mwdma_mask, d->udma_mask);
xfer_mask &= ata_id_xfermask(d->id);
if (ata_dma_blacklisted(d))
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
}
if (ata_dma_blacklisted(dev))
ata_dev_printk(dev, KERN_WARNING, ata_dev_printk(dev, KERN_WARNING,
"device is on DMA blacklist, disabling DMA\n"); "device is on DMA blacklist, disabling DMA\n");
}
if (hs->flags & ATA_HOST_SIMPLEX) { if ((hs->flags & ATA_HOST_SIMPLEX) && hs->simplex_claimed) {
if (hs->simplex_claimed)
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by "
"other device, disabling DMA\n");
} }
if (ap->ops->mode_filter) if (ap->ops->mode_filter)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment