mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-15 10:54:05 +00:00
[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>
This commit is contained in:
parent
2fc37adba0
commit
388539f3ff
4 changed files with 36 additions and 8 deletions
|
@ -2869,7 +2869,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
|
|
||||||
/* prepare host */
|
/* prepare host */
|
||||||
if (hpriv->cap & HOST_CAP_NCQ)
|
if (hpriv->cap & HOST_CAP_NCQ)
|
||||||
pi.flags |= ATA_FLAG_NCQ;
|
pi.flags |= ATA_FLAG_NCQ | ATA_FLAG_FPDMA_AA;
|
||||||
|
|
||||||
if (hpriv->cap & HOST_CAP_PMP)
|
if (hpriv->cap & HOST_CAP_PMP)
|
||||||
pi.flags |= ATA_FLAG_PMP;
|
pi.flags |= ATA_FLAG_PMP;
|
||||||
|
|
|
@ -2299,29 +2299,49 @@ static inline u8 ata_dev_knobble(struct ata_device *dev)
|
||||||
return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
|
return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ata_dev_config_ncq(struct ata_device *dev,
|
static int ata_dev_config_ncq(struct ata_device *dev,
|
||||||
char *desc, size_t desc_sz)
|
char *desc, size_t desc_sz)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = dev->link->ap;
|
struct ata_port *ap = dev->link->ap;
|
||||||
int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
|
int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
|
||||||
|
unsigned int err_mask;
|
||||||
|
char *aa_desc = "";
|
||||||
|
|
||||||
if (!ata_id_has_ncq(dev->id)) {
|
if (!ata_id_has_ncq(dev->id)) {
|
||||||
desc[0] = '\0';
|
desc[0] = '\0';
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (dev->horkage & ATA_HORKAGE_NONCQ) {
|
if (dev->horkage & ATA_HORKAGE_NONCQ) {
|
||||||
snprintf(desc, desc_sz, "NCQ (not used)");
|
snprintf(desc, desc_sz, "NCQ (not used)");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ap->flags & ATA_FLAG_NCQ) {
|
if (ap->flags & ATA_FLAG_NCQ) {
|
||||||
hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
|
hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
|
||||||
dev->flags |= ATA_DFLAG_NCQ;
|
dev->flags |= ATA_DFLAG_NCQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA) &&
|
||||||
|
(ap->flags & ATA_FLAG_FPDMA_AA) &&
|
||||||
|
ata_id_has_fpdma_aa(dev->id)) {
|
||||||
|
err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE,
|
||||||
|
SATA_FPDMA_AA);
|
||||||
|
if (err_mask) {
|
||||||
|
ata_dev_printk(dev, KERN_ERR, "failed to enable AA"
|
||||||
|
"(error_mask=0x%x)\n", err_mask);
|
||||||
|
if (err_mask != AC_ERR_DEV) {
|
||||||
|
dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA;
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
aa_desc = ", AA";
|
||||||
|
}
|
||||||
|
|
||||||
if (hdepth >= ddepth)
|
if (hdepth >= ddepth)
|
||||||
snprintf(desc, desc_sz, "NCQ (depth %d)", ddepth);
|
snprintf(desc, desc_sz, "NCQ (depth %d)%s", ddepth, aa_desc);
|
||||||
else
|
else
|
||||||
snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth);
|
snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth,
|
||||||
|
ddepth, aa_desc);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2461,7 +2481,7 @@ int ata_dev_configure(struct ata_device *dev)
|
||||||
|
|
||||||
if (ata_id_has_lba(id)) {
|
if (ata_id_has_lba(id)) {
|
||||||
const char *lba_desc;
|
const char *lba_desc;
|
||||||
char ncq_desc[20];
|
char ncq_desc[24];
|
||||||
|
|
||||||
lba_desc = "LBA";
|
lba_desc = "LBA";
|
||||||
dev->flags |= ATA_DFLAG_LBA;
|
dev->flags |= ATA_DFLAG_LBA;
|
||||||
|
@ -2475,7 +2495,9 @@ int ata_dev_configure(struct ata_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* config NCQ */
|
/* config NCQ */
|
||||||
ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
|
rc = ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
/* print device info to dmesg */
|
/* print device info to dmesg */
|
||||||
if (ata_msg_drv(ap) && print_info) {
|
if (ata_msg_drv(ap) && print_info) {
|
||||||
|
|
|
@ -306,6 +306,7 @@ enum {
|
||||||
/* SETFEATURE Sector counts for SATA features */
|
/* SETFEATURE Sector counts for SATA features */
|
||||||
SATA_AN = 0x05, /* Asynchronous Notification */
|
SATA_AN = 0x05, /* Asynchronous Notification */
|
||||||
SATA_DIPM = 0x03, /* Device Initiated Power Management */
|
SATA_DIPM = 0x03, /* Device Initiated Power Management */
|
||||||
|
SATA_FPDMA_AA = 0x02, /* DMA Setup FIS Auto-Activate */
|
||||||
|
|
||||||
/* feature values for SET_MAX */
|
/* feature values for SET_MAX */
|
||||||
ATA_SET_MAX_ADDR = 0x00,
|
ATA_SET_MAX_ADDR = 0x00,
|
||||||
|
@ -525,6 +526,9 @@ static inline int ata_is_data(u8 prot)
|
||||||
#define ata_id_has_atapi_AN(id) \
|
#define ata_id_has_atapi_AN(id) \
|
||||||
( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
|
( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
|
||||||
((id)[78] & (1 << 5)) )
|
((id)[78] & (1 << 5)) )
|
||||||
|
#define ata_id_has_fpdma_aa(id) \
|
||||||
|
( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
|
||||||
|
((id)[78] & (1 << 2)) )
|
||||||
#define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))
|
#define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))
|
||||||
#define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))
|
#define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))
|
||||||
#define ata_id_u32(id,n) \
|
#define ata_id_u32(id,n) \
|
||||||
|
|
|
@ -190,6 +190,7 @@ enum {
|
||||||
ATA_FLAG_NO_POWEROFF_SPINDOWN = (1 << 11), /* don't spindown before poweroff */
|
ATA_FLAG_NO_POWEROFF_SPINDOWN = (1 << 11), /* don't spindown before poweroff */
|
||||||
ATA_FLAG_NO_HIBERNATE_SPINDOWN = (1 << 12), /* don't spindown before hibernation */
|
ATA_FLAG_NO_HIBERNATE_SPINDOWN = (1 << 12), /* don't spindown before hibernation */
|
||||||
ATA_FLAG_DEBUGMSG = (1 << 13),
|
ATA_FLAG_DEBUGMSG = (1 << 13),
|
||||||
|
ATA_FLAG_FPDMA_AA = (1 << 14), /* driver supports Auto-Activate */
|
||||||
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
|
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
|
||||||
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
|
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
|
||||||
ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
|
ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
|
||||||
|
@ -386,6 +387,7 @@ enum {
|
||||||
ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firmware update warning */
|
ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firmware update warning */
|
||||||
ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */
|
ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */
|
||||||
ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */
|
ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */
|
||||||
|
ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */
|
||||||
|
|
||||||
/* DMA mask for user DMA control: User visible values; DO NOT
|
/* DMA mask for user DMA control: User visible values; DO NOT
|
||||||
renumber */
|
renumber */
|
||||||
|
|
Loading…
Add table
Reference in a new issue