Commit 9116300634c5c76cfcd0d2af689846e04d172256
Committed by
Jeff Garzik
1 parent
559bbe6cbd
Exists in
master
and in
7 other branches
libata: automatically use DMADIR if drive/bridge requires it
Back in 2.6.17-rc2, a libata module parameter was added for atapi_dmadir. That's nice, but most SATA devices which need it will tell us about it in their IDENTIFY PACKET response, as bit-15 of word-62 of the returned data (as per ATA7, ATA8 specifications). So for those which specify it, we should automatically use the DMADIR bit. Otherwise, disc writing will fail by default on many SATA-ATAPI drives. This patch adds ATA_DFLAG_DMADIR and make ata_dev_configure() set it if atapi_dmadir is set or identify data indicates DMADIR is necessary. atapi_xlat() is converted to check ATA_DFLAG_DMADIR before setting DMADIR. Original patch is from Mark Lord. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Showing 4 changed files with 17 additions and 3 deletions Side-by-side Diff
drivers/ata/libata-core.c
... | ... | @@ -2396,6 +2396,7 @@ |
2396 | 2396 | else if (dev->class == ATA_DEV_ATAPI) { |
2397 | 2397 | const char *cdb_intr_string = ""; |
2398 | 2398 | const char *atapi_an_string = ""; |
2399 | + const char *dma_dir_string = ""; | |
2399 | 2400 | u32 sntf; |
2400 | 2401 | |
2401 | 2402 | rc = atapi_cdb_len(id); |
2402 | 2403 | |
2403 | 2404 | |
... | ... | @@ -2436,13 +2437,19 @@ |
2436 | 2437 | cdb_intr_string = ", CDB intr"; |
2437 | 2438 | } |
2438 | 2439 | |
2440 | + if (atapi_dmadir || atapi_id_dmadir(dev->id)) { | |
2441 | + dev->flags |= ATA_DFLAG_DMADIR; | |
2442 | + dma_dir_string = ", DMADIR"; | |
2443 | + } | |
2444 | + | |
2439 | 2445 | /* print device info to dmesg */ |
2440 | 2446 | if (ata_msg_drv(ap) && print_info) |
2441 | 2447 | ata_dev_printk(dev, KERN_INFO, |
2442 | - "ATAPI: %s, %s, max %s%s%s\n", | |
2448 | + "ATAPI: %s, %s, max %s%s%s%s\n", | |
2443 | 2449 | modelbuf, fwrevbuf, |
2444 | 2450 | ata_mode_string(xfer_mask), |
2445 | - cdb_intr_string, atapi_an_string); | |
2451 | + cdb_intr_string, atapi_an_string, | |
2452 | + dma_dir_string); | |
2446 | 2453 | } |
2447 | 2454 | |
2448 | 2455 | /* determine max_sectors */ |
drivers/ata/libata-scsi.c
... | ... | @@ -2582,7 +2582,8 @@ |
2582 | 2582 | qc->tf.protocol = ATAPI_PROT_DMA; |
2583 | 2583 | qc->tf.feature |= ATAPI_PKT_DMA; |
2584 | 2584 | |
2585 | - if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE)) | |
2585 | + if ((dev->flags & ATA_DFLAG_DMADIR) && | |
2586 | + (scmd->sc_data_direction != DMA_TO_DEVICE)) | |
2586 | 2587 | /* some SATA bridges need us to indicate data xfer direction */ |
2587 | 2588 | qc->tf.feature |= ATAPI_DMADIR; |
2588 | 2589 | } |
include/linux/ata.h
... | ... | @@ -659,6 +659,11 @@ |
659 | 659 | return (dev_id[0] >> 8) & 0x1f; |
660 | 660 | } |
661 | 661 | |
662 | +static inline int atapi_id_dmadir(const u16 *dev_id) | |
663 | +{ | |
664 | + return ata_id_major_version(dev_id) >= 7 && (dev_id[62] & 0x8000); | |
665 | +} | |
666 | + | |
662 | 667 | static inline int is_multi_taskfile(struct ata_taskfile *tf) |
663 | 668 | { |
664 | 669 | return (tf->command == ATA_CMD_READ_MULTI) || |
include/linux/libata.h
... | ... | @@ -138,6 +138,7 @@ |
138 | 138 | ATA_DFLAG_AN = (1 << 7), /* AN configured */ |
139 | 139 | ATA_DFLAG_HIPM = (1 << 8), /* device supports HIPM */ |
140 | 140 | ATA_DFLAG_DIPM = (1 << 9), /* device supports DIPM */ |
141 | + ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */ | |
141 | 142 | ATA_DFLAG_CFG_MASK = (1 << 12) - 1, |
142 | 143 | |
143 | 144 | ATA_DFLAG_PIO = (1 << 12), /* device limited to PIO mode */ |