aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
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
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')
-rw-r--r--drivers/ata/libata-core.c105
-rw-r--r--drivers/ata/libata-eh.c9
-rw-r--r--drivers/ata/libata.h12
3 files changed, 96 insertions, 30 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)
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 52c85af7fe99..7b61562cdd40 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1276,7 +1276,7 @@ static int ata_eh_speed_down(struct ata_device *dev, int is_io,
1276 return ATA_EH_HARDRESET; 1276 return ATA_EH_HARDRESET;
1277 1277
1278 /* lower transfer mode */ 1278 /* lower transfer mode */
1279 if (ata_down_xfermask_limit(dev, 0) == 0) 1279 if (ata_down_xfermask_limit(dev, ATA_DNXFER_ANY) == 0)
1280 return ATA_EH_SOFTRESET; 1280 return ATA_EH_SOFTRESET;
1281 1281
1282 ata_dev_printk(dev, KERN_ERR, 1282 ata_dev_printk(dev, KERN_ERR,
@@ -1965,6 +1965,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
1965 struct ata_eh_context *ehc = &ap->eh_context; 1965 struct ata_eh_context *ehc = &ap->eh_context;
1966 struct ata_device *dev; 1966 struct ata_device *dev;
1967 int down_xfermask, i, rc; 1967 int down_xfermask, i, rc;
1968 int dnxfer_sel;
1968 1969
1969 DPRINTK("ENTER\n"); 1970 DPRINTK("ENTER\n");
1970 1971
@@ -2064,8 +2065,10 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
2064 sata_down_spd_limit(ap); 2065 sata_down_spd_limit(ap);
2065 default: 2066 default:
2066 ehc->tries[dev->devno]--; 2067 ehc->tries[dev->devno]--;
2067 if (down_xfermask && 2068 dnxfer_sel = ATA_DNXFER_ANY;
2068 ata_down_xfermask_limit(dev, ehc->tries[dev->devno] == 1)) 2069 if (ehc->tries[dev->devno] == 1)
2070 dnxfer_sel = ATA_DNXFER_FORCE_PIO0;
2071 if (down_xfermask && ata_down_xfermask_limit(dev, dnxfer_sel))
2069 ehc->tries[dev->devno] = 0; 2072 ehc->tries[dev->devno] = 0;
2070 } 2073 }
2071 2074
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 0ad7781d72a3..8533de67d87e 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -41,6 +41,16 @@ struct ata_scsi_args {
41enum { 41enum {
42 /* flags for ata_dev_read_id() */ 42 /* flags for ata_dev_read_id() */
43 ATA_READID_POSTRESET = (1 << 0), /* reading ID after reset */ 43 ATA_READID_POSTRESET = (1 << 0), /* reading ID after reset */
44
45 /* selector for ata_down_xfermask_limit() */
46 ATA_DNXFER_PIO = 0, /* speed down PIO */
47 ATA_DNXFER_DMA = 1, /* speed down DMA */
48 ATA_DNXFER_40C = 2, /* apply 40c cable limit */
49 ATA_DNXFER_FORCE_PIO = 3, /* force PIO */
50 ATA_DNXFER_FORCE_PIO0 = 4, /* force PIO0 */
51 ATA_DNXFER_ANY = 5, /* speed down any */
52
53 ATA_DNXFER_QUIET = (1 << 31),
44}; 54};
45 55
46extern struct workqueue_struct *ata_aux_wq; 56extern struct workqueue_struct *ata_aux_wq;
@@ -69,7 +79,7 @@ extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags);
69extern int ata_dev_configure(struct ata_device *dev); 79extern int ata_dev_configure(struct ata_device *dev);
70extern int sata_down_spd_limit(struct ata_port *ap); 80extern int sata_down_spd_limit(struct ata_port *ap);
71extern int sata_set_spd_needed(struct ata_port *ap); 81extern int sata_set_spd_needed(struct ata_port *ap);
72extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0); 82extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
73extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev); 83extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
74extern void ata_sg_clean(struct ata_queued_cmd *qc); 84extern void ata_sg_clean(struct ata_queued_cmd *qc);
75extern void ata_qc_free(struct ata_queued_cmd *qc); 85extern void ata_qc_free(struct ata_queued_cmd *qc);