aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorShaohua Li <shaohua.li@intel.com>2009-07-26 21:24:35 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-09-01 19:47:19 -0400
commit388539f3ff0cf1de926b03f94e1eec112358f74d (patch)
tree6840b76ede7e27e27eb9aaf516f827beba16c5ad /drivers/ata/libata-core.c
parent2fc37adba0fb05760b8635c6706773af828ccf3c (diff)
[libata] add DMA setup FIS auto-activate feature
Hopefully results in fewer on-the-wire FIS's and no breakage. We'll see! Signed-off-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 072ba5ea138f..98af50f16e0c 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2299,29 +2299,49 @@ static inline u8 ata_dev_knobble(struct ata_device *dev)
2299 return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); 2299 return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
2300} 2300}
2301 2301
2302static void ata_dev_config_ncq(struct ata_device *dev, 2302static int ata_dev_config_ncq(struct ata_device *dev,
2303 char *desc, size_t desc_sz) 2303 char *desc, size_t desc_sz)
2304{ 2304{
2305 struct ata_port *ap = dev->link->ap; 2305 struct ata_port *ap = dev->link->ap;
2306 int hdepth = 0, ddepth = ata_id_queue_depth(dev->id); 2306 int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
2307 unsigned int err_mask;
2308 char *aa_desc = "";
2307 2309
2308 if (!ata_id_has_ncq(dev->id)) { 2310 if (!ata_id_has_ncq(dev->id)) {
2309 desc[0] = '\0'; 2311 desc[0] = '\0';
2310 return; 2312 return 0;
2311 } 2313 }
2312 if (dev->horkage & ATA_HORKAGE_NONCQ) { 2314 if (dev->horkage & ATA_HORKAGE_NONCQ) {
2313 snprintf(desc, desc_sz, "NCQ (not used)"); 2315 snprintf(desc, desc_sz, "NCQ (not used)");
2314 return; 2316 return 0;
2315 } 2317 }
2316 if (ap->flags & ATA_FLAG_NCQ) { 2318 if (ap->flags & ATA_FLAG_NCQ) {
2317 hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1); 2319 hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
2318 dev->flags |= ATA_DFLAG_NCQ; 2320 dev->flags |= ATA_DFLAG_NCQ;
2319 } 2321 }
2320 2322
2323 if (!(dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA) &&
2324 (ap->flags & ATA_FLAG_FPDMA_AA) &&
2325 ata_id_has_fpdma_aa(dev->id)) {
2326 err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE,
2327 SATA_FPDMA_AA);
2328 if (err_mask) {
2329 ata_dev_printk(dev, KERN_ERR, "failed to enable AA"
2330 "(error_mask=0x%x)\n", err_mask);
2331 if (err_mask != AC_ERR_DEV) {
2332 dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA;
2333 return -EIO;
2334 }
2335 } else
2336 aa_desc = ", AA";
2337 }
2338
2321 if (hdepth >= ddepth) 2339 if (hdepth >= ddepth)
2322 snprintf(desc, desc_sz, "NCQ (depth %d)", ddepth); 2340 snprintf(desc, desc_sz, "NCQ (depth %d)%s", ddepth, aa_desc);
2323 else 2341 else
2324 snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth); 2342 snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth,
2343 ddepth, aa_desc);
2344 return 0;
2325} 2345}
2326 2346
2327/** 2347/**
@@ -2461,7 +2481,7 @@ int ata_dev_configure(struct ata_device *dev)
2461 2481
2462 if (ata_id_has_lba(id)) { 2482 if (ata_id_has_lba(id)) {
2463 const char *lba_desc; 2483 const char *lba_desc;
2464 char ncq_desc[20]; 2484 char ncq_desc[24];
2465 2485
2466 lba_desc = "LBA"; 2486 lba_desc = "LBA";
2467 dev->flags |= ATA_DFLAG_LBA; 2487 dev->flags |= ATA_DFLAG_LBA;
@@ -2475,7 +2495,9 @@ int ata_dev_configure(struct ata_device *dev)
2475 } 2495 }
2476 2496
2477 /* config NCQ */ 2497 /* config NCQ */
2478 ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc)); 2498 rc = ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
2499 if (rc)
2500 return rc;
2479 2501
2480 /* print device info to dmesg */ 2502 /* print device info to dmesg */
2481 if (ata_msg_drv(ap) && print_info) { 2503 if (ata_msg_drv(ap) && print_info) {