X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fscsi%2Flibata-core.c;h=a28569d0081dfe6e052f63573e4147182c43dfe3;hb=41ade50c4eff9477e6aef6b15e84673c6758ec0d;hp=6d8aa86f2f6b0eac7827491d2218ad8d8bc43c62;hpb=2e755f68ee23b03484fde18d978f910cc5479cb8;p=linux-2.6 diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 6d8aa86f2f..a28569d008 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -65,16 +65,13 @@ static unsigned int ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); static void ata_set_mode(struct ata_port *ap); static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); -static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift); -static int fgb(u32 bitmap); -static int ata_choose_xfer_mode(const struct ata_port *ap, - u8 *xfer_mode_out, - unsigned int *xfer_shift_out); +static unsigned int ata_dev_xfermask(struct ata_port *ap, + struct ata_device *dev); static unsigned int ata_unique_id = 1; static struct workqueue_struct *ata_wq; -int atapi_enabled = 0; +int atapi_enabled = 1; module_param(atapi_enabled, int, 0444); MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); @@ -231,58 +228,148 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc) return -1; } -static const char * const xfer_mode_str[] = { - "UDMA/16", - "UDMA/25", - "UDMA/33", - "UDMA/44", - "UDMA/66", - "UDMA/100", - "UDMA/133", - "UDMA7", - "MWDMA0", - "MWDMA1", - "MWDMA2", - "PIO0", - "PIO1", - "PIO2", - "PIO3", - "PIO4", +/** + * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask + * @pio_mask: pio_mask + * @mwdma_mask: mwdma_mask + * @udma_mask: udma_mask + * + * Pack @pio_mask, @mwdma_mask and @udma_mask into a single + * unsigned int xfer_mask. + * + * LOCKING: + * None. + * + * RETURNS: + * Packed xfer_mask. + */ +static unsigned int ata_pack_xfermask(unsigned int pio_mask, + unsigned int mwdma_mask, + unsigned int udma_mask) +{ + return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) | + ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) | + ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA); +} + +static const struct ata_xfer_ent { + unsigned int shift, bits; + u8 base; +} ata_xfer_tbl[] = { + { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, + { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 }, + { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 }, + { -1, }, }; /** - * ata_udma_string - convert UDMA bit offset to string - * @mask: mask of bits supported; only highest bit counts. + * ata_xfer_mask2mode - Find matching XFER_* for the given xfer_mask + * @xfer_mask: xfer_mask of interest * - * Determine string which represents the highest speed - * (highest bit in @udma_mask). + * Return matching XFER_* value for @xfer_mask. Only the highest + * bit of @xfer_mask is considered. * * LOCKING: * None. * * RETURNS: - * Constant C string representing highest speed listed in - * @udma_mask, or the constant C string "". + * Matching XFER_* value, 0 if no match found. */ +static u8 ata_xfer_mask2mode(unsigned int xfer_mask) +{ + int highbit = fls(xfer_mask) - 1; + const struct ata_xfer_ent *ent; -static const char *ata_mode_string(unsigned int mask) + for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) + if (highbit >= ent->shift && highbit < ent->shift + ent->bits) + return ent->base + highbit - ent->shift; + return 0; +} + +/** + * ata_xfer_mode2mask - Find matching xfer_mask for XFER_* + * @xfer_mode: XFER_* of interest + * + * Return matching xfer_mask for @xfer_mode. + * + * LOCKING: + * None. + * + * RETURNS: + * Matching xfer_mask, 0 if no match found. + */ +static unsigned int ata_xfer_mode2mask(u8 xfer_mode) { - int i; + const struct ata_xfer_ent *ent; - for (i = 7; i >= 0; i--) - if (mask & (1 << i)) - goto out; - for (i = ATA_SHIFT_MWDMA + 2; i >= ATA_SHIFT_MWDMA; i--) - if (mask & (1 << i)) - goto out; - for (i = ATA_SHIFT_PIO + 4; i >= ATA_SHIFT_PIO; i--) - if (mask & (1 << i)) - goto out; + for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) + if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits) + return 1 << (ent->shift + xfer_mode - ent->base); + return 0; +} - return ""; +/** + * ata_xfer_mode2shift - Find matching xfer_shift for XFER_* + * @xfer_mode: XFER_* of interest + * + * Return matching xfer_shift for @xfer_mode. + * + * LOCKING: + * None. + * + * RETURNS: + * Matching xfer_shift, -1 if no match found. + */ +static int ata_xfer_mode2shift(unsigned int xfer_mode) +{ + const struct ata_xfer_ent *ent; -out: - return xfer_mode_str[i]; + for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) + if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits) + return ent->shift; + return -1; +} + +/** + * ata_mode_string - convert xfer_mask to string + * @xfer_mask: mask of bits supported; only highest bit counts. + * + * Determine string which represents the highest speed + * (highest bit in @modemask). + * + * LOCKING: + * None. + * + * RETURNS: + * Constant C string representing highest speed listed in + * @mode_mask, or the constant C string "". + */ +static const char *ata_mode_string(unsigned int xfer_mask) +{ + static const char * const xfer_mode_str[] = { + "PIO0", + "PIO1", + "PIO2", + "PIO3", + "PIO4", + "MWDMA0", + "MWDMA1", + "MWDMA2", + "UDMA/16", + "UDMA/25", + "UDMA/33", + "UDMA/44", + "UDMA/66", + "UDMA/100", + "UDMA/133", + "UDMA7", + }; + int highbit; + + highbit = fls(xfer_mask) - 1; + if (highbit >= 0 && highbit < ARRAY_SIZE(xfer_mode_str)) + return xfer_mode_str[highbit]; + return ""; } /** @@ -692,33 +779,52 @@ static inline void ata_dump_id(const u16 *id) id[93]); } -/* - * Compute the PIO modes available for this device. This is not as - * trivial as it seems if we must consider early devices correctly. +/** + * ata_id_xfermask - Compute xfermask from the given IDENTIFY data + * @id: IDENTIFY data to compute xfer mask from * - * FIXME: pre IDE drive timing (do we care ?). + * Compute the xfermask for this device. This is not as trivial + * as it seems if we must consider early devices correctly. + * + * FIXME: pre IDE drive timing (do we care ?). + * + * LOCKING: + * None. + * + * RETURNS: + * Computed xfermask */ - -static unsigned int ata_pio_modes(const struct ata_device *adev) +static unsigned int ata_id_xfermask(const u16 *id) { - u16 modes; + unsigned int pio_mask, mwdma_mask, udma_mask; /* Usual case. Word 53 indicates word 64 is valid */ - if (adev->id[ATA_ID_FIELD_VALID] & (1 << 1)) { - modes = adev->id[ATA_ID_PIO_MODES] & 0x03; - modes <<= 3; - modes |= 0x7; - return modes; + if (id[ATA_ID_FIELD_VALID] & (1 << 1)) { + pio_mask = id[ATA_ID_PIO_MODES] & 0x03; + pio_mask <<= 3; + pio_mask |= 0x7; + } else { + /* If word 64 isn't valid then Word 51 high byte holds + * the PIO timing number for the maximum. Turn it into + * a mask. + */ + pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ; + + /* But wait.. there's more. Design your standards by + * committee and you too can get a free iordy field to + * process. However its the speeds not the modes that + * are supported... Note drivers using the timing API + * will get this right anyway + */ } - /* If word 64 isn't valid then Word 51 high byte holds the PIO timing - number for the maximum. Turn it into a mask and return it */ - modes = (2 << ((adev->id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF)) - 1 ; - return modes; - /* But wait.. there's more. Design your standards by committee and - you too can get a free iordy field to process. However its the - speeds not the modes that are supported... Note drivers using the - timing API will get this right anyway */ + mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07; + + udma_mask = 0; + if (id[ATA_ID_FIELD_VALID] & (1 << 2)) + udma_mask = id[ATA_ID_UDMA_MODES] & 0xff; + + return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); } /** @@ -856,6 +962,8 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, spin_unlock_irqrestore(&ap->host_set->lock, flags); if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) { + ata_port_flush_task(ap); + spin_lock_irqsave(&ap->host_set->lock, flags); /* We're racing with irq here. If we lose, the @@ -1014,12 +1122,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, swap_buf_le16(id, ATA_ID_WORDS); - /* print device capabilities */ - printk(KERN_DEBUG "ata%u: dev %u cfg " - "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", - ap->id, dev->devno, - id[49], id[82], id[83], id[84], id[85], id[86], id[87], id[88]); - /* sanity check */ if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) { rc = -EINVAL; @@ -1087,7 +1189,8 @@ static inline u8 ata_dev_knobble(const struct ata_port *ap, static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, int print_info) { - unsigned long xfer_modes; + const u16 *id = dev->id; + unsigned int xfer_mask; int i, rc; if (!ata_dev_present(dev)) { @@ -1098,6 +1201,13 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); + /* print device capabilities */ + if (print_info) + printk(KERN_DEBUG "ata%u: dev %u cfg 49:%04x 82:%04x 83:%04x " + "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", + ap->id, dev->devno, id[49], id[82], id[83], + id[84], id[85], id[86], id[87], id[88]); + /* initialize to-be-configured parameters */ dev->flags = 0; dev->max_sectors = 0; @@ -1112,31 +1222,27 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, */ /* we require DMA support (bits 8 of word 49) */ - if (!ata_id_has_dma(dev->id)) { + if (!ata_id_has_dma(id)) { printk(KERN_DEBUG "ata%u: no dma\n", ap->id); rc = -EINVAL; goto err_out_nosup; } - /* quick-n-dirty find max transfer mode; for printk only */ - xfer_modes = dev->id[ATA_ID_UDMA_MODES]; - if (!xfer_modes) - xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA; - if (!xfer_modes) - xfer_modes = ata_pio_modes(dev); + /* find max transfer mode; for printk only */ + xfer_mask = ata_id_xfermask(id); - ata_dump_id(dev->id); + ata_dump_id(id); /* ATA-specific feature tests */ if (dev->class == ATA_DEV_ATA) { - dev->n_sectors = ata_id_n_sectors(dev->id); + dev->n_sectors = ata_id_n_sectors(id); - if (ata_id_has_lba(dev->id)) { + if (ata_id_has_lba(id)) { const char *lba_desc; lba_desc = "LBA"; dev->flags |= ATA_DFLAG_LBA; - if (ata_id_has_lba48(dev->id)) { + if (ata_id_has_lba48(id)) { dev->flags |= ATA_DFLAG_LBA48; lba_desc = "LBA48"; } @@ -1146,23 +1252,23 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, printk(KERN_INFO "ata%u: dev %u ATA-%d, " "max %s, %Lu sectors: %s\n", ap->id, dev->devno, - ata_id_major_version(dev->id), - ata_mode_string(xfer_modes), + ata_id_major_version(id), + ata_mode_string(xfer_mask), (unsigned long long)dev->n_sectors, lba_desc); } else { /* CHS */ /* Default translation */ - dev->cylinders = dev->id[1]; - dev->heads = dev->id[3]; - dev->sectors = dev->id[6]; + dev->cylinders = id[1]; + dev->heads = id[3]; + dev->sectors = id[6]; - if (ata_id_current_chs_valid(dev->id)) { + if (ata_id_current_chs_valid(id)) { /* Current CHS translation is valid. */ - dev->cylinders = dev->id[54]; - dev->heads = dev->id[55]; - dev->sectors = dev->id[56]; + dev->cylinders = id[54]; + dev->heads = id[55]; + dev->sectors = id[56]; } /* print device info to dmesg */ @@ -1170,8 +1276,8 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, printk(KERN_INFO "ata%u: dev %u ATA-%d, " "max %s, %Lu sectors: CHS %u/%u/%u\n", ap->id, dev->devno, - ata_id_major_version(dev->id), - ata_mode_string(xfer_modes), + ata_id_major_version(id), + ata_mode_string(xfer_mask), (unsigned long long)dev->n_sectors, dev->cylinders, dev->heads, dev->sectors); } @@ -1181,7 +1287,7 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, /* ATAPI-specific feature tests */ else if (dev->class == ATA_DEV_ATAPI) { - rc = atapi_cdb_len(dev->id); + rc = atapi_cdb_len(id); if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id); rc = -EINVAL; @@ -1192,7 +1298,7 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, /* print device info to dmesg */ if (print_info) printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n", - ap->id, dev->devno, ata_mode_string(xfer_modes)); + ap->id, dev->devno, ata_mode_string(xfer_mask)); } ap->host->max_cmd_len = 0; @@ -1245,29 +1351,30 @@ static int ata_bus_probe(struct ata_port *ap) ata_port_probe(ap); - /* reset */ + /* reset and determine device classes */ + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ATA_DEV_UNKNOWN; + if (ap->ops->probe_reset) { rc = ap->ops->probe_reset(ap, classes); if (rc) { printk("ata%u: reset failed (errno=%d)\n", ap->id, rc); return rc; } - - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (classes[i] == ATA_DEV_UNKNOWN) - classes[i] = ATA_DEV_NONE; } else { ap->ops->phy_reset(ap); - for (i = 0; i < ATA_MAX_DEVICES; i++) { - if (!(ap->flags & ATA_FLAG_PORT_DISABLED)) + if (!(ap->flags & ATA_FLAG_PORT_DISABLED)) + for (i = 0; i < ATA_MAX_DEVICES; i++) classes[i] = ap->device[i].class; - else - ap->device[i].class = ATA_DEV_UNKNOWN; - } + ata_port_probe(ap); } + for (i = 0; i < ATA_MAX_DEVICES; i++) + if (classes[i] == ATA_DEV_UNKNOWN) + classes[i] = ATA_DEV_NONE; + /* read IDENTIFY page and configure devices */ for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; @@ -1597,31 +1704,8 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, return 0; } -static const struct { - unsigned int shift; - u8 base; -} xfer_mode_classes[] = { - { ATA_SHIFT_UDMA, XFER_UDMA_0 }, - { ATA_SHIFT_MWDMA, XFER_MW_DMA_0 }, - { ATA_SHIFT_PIO, XFER_PIO_0 }, -}; - -static u8 base_from_shift(unsigned int shift) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) - if (xfer_mode_classes[i].shift == shift) - return xfer_mode_classes[i].base; - - return 0xff; -} - static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) { - int ofs, idx; - u8 base; - if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED)) return; @@ -1630,71 +1714,58 @@ static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) ata_dev_set_xfermode(ap, dev); - base = base_from_shift(dev->xfer_shift); - ofs = dev->xfer_mode - base; - idx = ofs + dev->xfer_shift; - WARN_ON(idx >= ARRAY_SIZE(xfer_mode_str)); - if (ata_dev_revalidate(ap, dev, 0)) { printk(KERN_ERR "ata%u: failed to revalidate after set " "xfermode, disabled\n", ap->id); ata_port_disable(ap); } - DPRINTK("idx=%d xfer_shift=%u, xfer_mode=0x%x, base=0x%x, offset=%d\n", - idx, dev->xfer_shift, (int)dev->xfer_mode, (int)base, ofs); + DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n", + dev->xfer_shift, (int)dev->xfer_mode); printk(KERN_INFO "ata%u: dev %u configured for %s\n", - ap->id, dev->devno, xfer_mode_str[idx]); + ap->id, dev->devno, + ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode))); } static int ata_host_set_pio(struct ata_port *ap) { - unsigned int mask; - int x, i; - u8 base, xfer_mode; - - mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO); - x = fgb(mask); - if (x < 0) { - printk(KERN_WARNING "ata%u: no PIO support\n", ap->id); - return -1; - } - - base = base_from_shift(ATA_SHIFT_PIO); - xfer_mode = base + x; - - DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n", - (int)base, (int)xfer_mode, mask, x); + int i; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_present(dev)) { - dev->pio_mode = xfer_mode; - dev->xfer_mode = xfer_mode; - dev->xfer_shift = ATA_SHIFT_PIO; - if (ap->ops->set_piomode) - ap->ops->set_piomode(ap, dev); + + if (!ata_dev_present(dev)) + continue; + + if (!dev->pio_mode) { + printk(KERN_WARNING "ata%u: no PIO support\n", ap->id); + return -1; } + + dev->xfer_mode = dev->pio_mode; + dev->xfer_shift = ATA_SHIFT_PIO; + if (ap->ops->set_piomode) + ap->ops->set_piomode(ap, dev); } return 0; } -static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, - unsigned int xfer_shift) +static void ata_host_set_dma(struct ata_port *ap) { int i; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_present(dev)) { - dev->dma_mode = xfer_mode; - dev->xfer_mode = xfer_mode; - dev->xfer_shift = xfer_shift; - if (ap->ops->set_dmamode) - ap->ops->set_dmamode(ap, dev); - } + + if (!ata_dev_present(dev) || !dev->dma_mode) + continue; + + dev->xfer_mode = dev->dma_mode; + dev->xfer_shift = ata_xfer_mode2shift(dev->dma_mode); + if (ap->ops->set_dmamode) + ap->ops->set_dmamode(ap, dev); } } @@ -1709,28 +1780,34 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, */ static void ata_set_mode(struct ata_port *ap) { - unsigned int xfer_shift; - u8 xfer_mode; - int rc; + int i, rc; - /* step 1: always set host PIO timings */ - rc = ata_host_set_pio(ap); - if (rc) - goto err_out; + /* step 1: calculate xfer_mask */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + unsigned int xfer_mask; - /* step 2: choose the best data xfer mode */ - xfer_mode = xfer_shift = 0; - rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift); + if (!ata_dev_present(dev)) + continue; + + xfer_mask = ata_dev_xfermask(ap, dev); + + dev->pio_mode = ata_xfer_mask2mode(xfer_mask & ATA_MASK_PIO); + dev->dma_mode = ata_xfer_mask2mode(xfer_mask & (ATA_MASK_MWDMA | + ATA_MASK_UDMA)); + } + + /* step 2: always set host PIO timings */ + rc = ata_host_set_pio(ap); if (rc) goto err_out; - /* step 3: if that xfer mode isn't PIO, set host DMA timings */ - if (xfer_shift != ATA_SHIFT_PIO) - ata_host_set_dma(ap, xfer_mode, xfer_shift); + /* step 3: set host DMA timings */ + ata_host_set_dma(ap); /* step 4: update devices' xfer mode */ - ata_dev_set_mode(ap, &ap->device[0]); - ata_dev_set_mode(ap, &ap->device[1]); + for (i = 0; i < ATA_MAX_DEVICES; i++) + ata_dev_set_mode(ap, &ap->device[i]); if (ap->flags & ATA_FLAG_PORT_DISABLED) return; @@ -2475,13 +2552,6 @@ int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev, return rc; } -static void ata_pr_blacklisted(const struct ata_port *ap, - const struct ata_device *dev) -{ - printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n", - ap->id, dev->devno); -} - static const char * const ata_dma_blacklist [] = { "WDC AC11000H", "WDC AC22100H", @@ -2528,128 +2598,45 @@ static int ata_dma_blacklisted(const struct ata_device *dev) return 0; } -static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift) -{ - const struct ata_device *master, *slave; - unsigned int mask; - - master = &ap->device[0]; - slave = &ap->device[1]; - - WARN_ON(!ata_dev_present(master) && !ata_dev_present(slave)); - - if (shift == ATA_SHIFT_UDMA) { - mask = ap->udma_mask; - if (ata_dev_present(master)) { - mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); - if (ata_dma_blacklisted(master)) { - mask = 0; - ata_pr_blacklisted(ap, master); - } - } - if (ata_dev_present(slave)) { - mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff); - if (ata_dma_blacklisted(slave)) { - mask = 0; - ata_pr_blacklisted(ap, slave); - } - } - } - else if (shift == ATA_SHIFT_MWDMA) { - mask = ap->mwdma_mask; - if (ata_dev_present(master)) { - mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07); - if (ata_dma_blacklisted(master)) { - mask = 0; - ata_pr_blacklisted(ap, master); - } - } - if (ata_dev_present(slave)) { - mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07); - if (ata_dma_blacklisted(slave)) { - mask = 0; - ata_pr_blacklisted(ap, slave); - } - } - } - else if (shift == ATA_SHIFT_PIO) { - mask = ap->pio_mask; - if (ata_dev_present(master)) { - /* spec doesn't return explicit support for - * PIO0-2, so we fake it - */ - u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03; - tmp_mode <<= 3; - tmp_mode |= 0x7; - mask &= tmp_mode; - } - if (ata_dev_present(slave)) { - /* spec doesn't return explicit support for - * PIO0-2, so we fake it - */ - u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03; - tmp_mode <<= 3; - tmp_mode |= 0x7; - mask &= tmp_mode; - } - } - else { - mask = 0xffffffff; /* shut up compiler warning */ - BUG(); - } - - return mask; -} - -/* find greatest bit */ -static int fgb(u32 bitmap) -{ - unsigned int i; - int x = -1; - - for (i = 0; i < 32; i++) - if (bitmap & (1 << i)) - x = i; - - return x; -} - /** - * ata_choose_xfer_mode - attempt to find best transfer mode - * @ap: Port for which an xfer mode will be selected - * @xfer_mode_out: (output) SET FEATURES - XFER MODE code - * @xfer_shift_out: (output) bit shift that selects this mode + * ata_dev_xfermask - Compute supported xfermask of the given device + * @ap: Port on which the device to compute xfermask for resides + * @dev: Device to compute xfermask for * - * Based on host and device capabilities, determine the - * maximum transfer mode that is amenable to all. + * Compute supported xfermask of @dev. This function is + * responsible for applying all known limits including host + * controller limits, device blacklist, etc... * * LOCKING: - * PCI/etc. bus probe sem. + * None. * * RETURNS: - * Zero on success, negative on error. + * Computed xfermask. */ - -static int ata_choose_xfer_mode(const struct ata_port *ap, - u8 *xfer_mode_out, - unsigned int *xfer_shift_out) +static unsigned int ata_dev_xfermask(struct ata_port *ap, + struct ata_device *dev) { - unsigned int mask, shift; - int x, i; + unsigned long xfer_mask; + int i; - for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) { - shift = xfer_mode_classes[i].shift; - mask = ata_get_mode_mask(ap, shift); + xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, + ap->udma_mask); - x = fgb(mask); - if (x >= 0) { - *xfer_mode_out = xfer_mode_classes[i].base + x; - *xfer_shift_out = shift; - return 0; - } + /* use port-wide xfermask for now */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *d = &ap->device[i]; + if (!ata_dev_present(d)) + continue; + xfer_mask &= ata_id_xfermask(d->id); + if (ata_dma_blacklisted(d)) + xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); } - return -1; + if (ata_dma_blacklisted(dev)) + printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " + "disabling DMA\n", ap->id, dev->devno); + + return xfer_mask; } /**