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)
* known limits including host controller limits, device
* 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:
* None.
*/
......@@ -3052,8 +3048,8 @@ static void ata_dev_xfermask(struct ata_device *dev)
struct ata_port *ap = dev->ap;
struct ata_host_set *hs = ap->host_set;
unsigned long xfer_mask;
int i;
/* controller modes available */
xfer_mask = ata_pack_xfermask(ap->pio_mask,
ap->mwdma_mask, ap->udma_mask);
......@@ -3063,34 +3059,20 @@ static void ata_dev_xfermask(struct ata_device *dev)
if (ap->cbl == ATA_CBL_PATA40)
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
/* FIXME: Use port-wide xfermask for now */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *d = &ap->device[i];
if (ata_dev_absent(d))
continue;
xfer_mask &= ata_pack_xfermask(dev->pio_mask,
dev->mwdma_mask, dev->udma_mask);
xfer_mask &= ata_id_xfermask(dev->id);
if (ata_dev_disabled(d)) {
/* 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))
if (ata_dma_blacklisted(dev)) {
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
}
if (ata_dma_blacklisted(dev))
ata_dev_printk(dev, KERN_WARNING,
"device is on DMA blacklist, disabling DMA\n");
}
if (hs->flags & ATA_HOST_SIMPLEX) {
if (hs->simplex_claimed)
if ((hs->flags & ATA_HOST_SIMPLEX) && hs->simplex_claimed) {
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)
......
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