aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-02-02 02:22:30 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-21 04:58:16 -0500
commit458337dbb120d33f326e2b19d54eca8cf179b5c0 (patch)
tree91bc5284430b5a8856ec1b2fd4c277c4eb3f8827 /drivers/ata/libata-core.c
parenta619f981b477035027dd27dfbee6148b4cd4a83c (diff)
libata: improve ata_down_xfermask_limit()
Make ata_down_xfermask_limit() accept @sel instead of @force_pio0. @sel selects how the xfermask limit will be adjusted. The following selectors are defined. * ATA_DNXFER_PIO : only speed down PIO * ATA_DNXFER_DMA : only speed down DMA, don't cause transfer mode change * ATA_DNXFER_40C : apply 40c cable limit * ATA_DNXFER_FORCE_PIO : force PIO * ATA_DNXFER_FORCE_PIO0 : force PIO0 (same as original with @force_pio0 == 1) * ATA_DNXFER_ANY : same as original with @force_pio0 == 0 Currently, only ANY and FORCE_PIO0 are used to maintain the original behavior. Other selectors will be used later to improve EH speed down sequence. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c105
1 files changed, 79 insertions, 26 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 9c54de5addff..249d487c091e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1780,6 +1780,7 @@ int ata_bus_probe(struct ata_port *ap)
1780 int tries[ATA_MAX_DEVICES]; 1780 int tries[ATA_MAX_DEVICES];
1781 int i, rc, down_xfermask; 1781 int i, rc, down_xfermask;
1782 struct ata_device *dev; 1782 struct ata_device *dev;
1783 int dnxfer_sel;
1783 1784
1784 ata_port_probe(ap); 1785 ata_port_probe(ap);
1785 1786
@@ -1861,13 +1862,15 @@ int ata_bus_probe(struct ata_port *ap)
1861 /* fall through */ 1862 /* fall through */
1862 default: 1863 default:
1863 tries[dev->devno]--; 1864 tries[dev->devno]--;
1864 if (down_xfermask && 1865 dnxfer_sel = ATA_DNXFER_ANY;
1865 ata_down_xfermask_limit(dev, tries[dev->devno] == 1)) 1866 if (tries[dev->devno] == 1)
1867 dnxfer_sel = ATA_DNXFER_FORCE_PIO0;
1868 if (down_xfermask && ata_down_xfermask_limit(dev, dnxfer_sel))
1866 tries[dev->devno] = 0; 1869 tries[dev->devno] = 0;
1867 } 1870 }
1868 1871
1869 if (!tries[dev->devno]) { 1872 if (!tries[dev->devno]) {
1870 ata_down_xfermask_limit(dev, 1); 1873 ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0);
1871 ata_dev_disable(dev); 1874 ata_dev_disable(dev);
1872 } 1875 }
1873 1876
@@ -2300,7 +2303,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
2300/** 2303/**
2301 * ata_down_xfermask_limit - adjust dev xfer masks downward 2304 * ata_down_xfermask_limit - adjust dev xfer masks downward
2302 * @dev: Device to adjust xfer masks 2305 * @dev: Device to adjust xfer masks
2303 * @force_pio0: Force PIO0 2306 * @sel: ATA_DNXFER_* selector
2304 * 2307 *
2305 * Adjust xfer masks of @dev downward. Note that this function 2308 * Adjust xfer masks of @dev downward. Note that this function
2306 * does not apply the change. Invoking ata_set_mode() afterwards 2309 * does not apply the change. Invoking ata_set_mode() afterwards
@@ -2312,37 +2315,87 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
2312 * RETURNS: 2315 * RETURNS:
2313 * 0 on success, negative errno on failure 2316 * 0 on success, negative errno on failure
2314 */ 2317 */
2315int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0) 2318int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel)
2316{ 2319{
2317 unsigned long xfer_mask; 2320 char buf[32];
2318 int highbit; 2321 unsigned int orig_mask, xfer_mask;
2322 unsigned int pio_mask, mwdma_mask, udma_mask;
2323 int quiet, highbit;
2319 2324
2320 xfer_mask = ata_pack_xfermask(dev->pio_mask, dev->mwdma_mask, 2325 quiet = !!(sel & ATA_DNXFER_QUIET);
2321 dev->udma_mask); 2326 sel &= ~ATA_DNXFER_QUIET;
2322 2327
2323 if (!xfer_mask) 2328 xfer_mask = orig_mask = ata_pack_xfermask(dev->pio_mask,
2324 goto fail; 2329 dev->mwdma_mask,
2325 /* don't gear down to MWDMA from UDMA, go directly to PIO */ 2330 dev->udma_mask);
2326 if (xfer_mask & ATA_MASK_UDMA) 2331 ata_unpack_xfermask(xfer_mask, &pio_mask, &mwdma_mask, &udma_mask);
2327 xfer_mask &= ~ATA_MASK_MWDMA;
2328 2332
2329 highbit = fls(xfer_mask) - 1; 2333 switch (sel) {
2330 xfer_mask &= ~(1 << highbit); 2334 case ATA_DNXFER_PIO:
2331 if (force_pio0) 2335 highbit = fls(pio_mask) - 1;
2332 xfer_mask &= 1 << ATA_SHIFT_PIO; 2336 pio_mask &= ~(1 << highbit);
2333 if (!xfer_mask) 2337 break;
2334 goto fail; 2338
2339 case ATA_DNXFER_DMA:
2340 if (udma_mask) {
2341 highbit = fls(udma_mask) - 1;
2342 udma_mask &= ~(1 << highbit);
2343 if (!udma_mask)
2344 return -ENOENT;
2345 } else if (mwdma_mask) {
2346 highbit = fls(mwdma_mask) - 1;
2347 mwdma_mask &= ~(1 << highbit);
2348 if (!mwdma_mask)
2349 return -ENOENT;
2350 }
2351 break;
2352
2353 case ATA_DNXFER_40C:
2354 udma_mask &= ATA_UDMA_MASK_40C;
2355 break;
2356
2357 case ATA_DNXFER_FORCE_PIO0:
2358 pio_mask &= 1;
2359 case ATA_DNXFER_FORCE_PIO:
2360 mwdma_mask = 0;
2361 udma_mask = 0;
2362 break;
2363
2364 case ATA_DNXFER_ANY:
2365 /* don't gear down to MWDMA from UDMA, go directly to PIO */
2366 if (xfer_mask & ATA_MASK_UDMA)
2367 xfer_mask &= ~ATA_MASK_MWDMA;
2368
2369 highbit = fls(xfer_mask) - 1;
2370 xfer_mask &= ~(1 << highbit);
2371 break;
2372
2373 default:
2374 BUG();
2375 }
2376
2377 xfer_mask &= ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);
2378
2379 if (!(xfer_mask & ATA_MASK_PIO) || xfer_mask == orig_mask)
2380 return -ENOENT;
2381
2382 if (!quiet) {
2383 if (xfer_mask & (ATA_MASK_MWDMA | ATA_MASK_UDMA))
2384 snprintf(buf, sizeof(buf), "%s:%s",
2385 ata_mode_string(xfer_mask),
2386 ata_mode_string(xfer_mask & ATA_MASK_PIO));
2387 else
2388 snprintf(buf, sizeof(buf), "%s",
2389 ata_mode_string(xfer_mask));
2390
2391 ata_dev_printk(dev, KERN_WARNING,
2392 "limiting speed to %s\n", buf);
2393 }
2335 2394
2336 ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, 2395 ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask,
2337 &dev->udma_mask); 2396 &dev->udma_mask);
2338 2397
2339 ata_dev_printk(dev, KERN_WARNING, "limiting speed to %s\n",
2340 ata_mode_string(xfer_mask));
2341
2342 return 0; 2398 return 0;
2343
2344 fail:
2345 return -EINVAL;
2346} 2399}
2347 2400
2348static int ata_dev_set_mode(struct ata_device *dev) 2401static int ata_dev_set_mode(struct ata_device *dev)