mirror of
https://github.com/adulau/aha.git
synced 2025-01-03 22:53:18 +00:00
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: [libata] pata_it821x: fix warning libata: Fix a large collection of DMA mode mismatches ahci: sis controllers actually can do PMP pata_via: clean up recent tf_load changes libata: restore SControl on detach libata: use ata_link_printk() when printing SError libata: always do follow-up SRST if hardreset returned -EAGAIN libata: fix EH action overwriting in ata_eh_reset() sata_mv: add the Gen IIE flag to the SoC devices. ata_piix: IDE Mode SATA patch for Intel Ibex Peak DeviceIDs ahci: RAID mode SATA patch for Intel Ibex Peak DeviceIDs sata_mv: don't issue two DMA commands concurrently libata: implement no[hs]rst force params
This commit is contained in:
commit
a7b354e868
14 changed files with 123 additions and 126 deletions
|
@ -1074,6 +1074,9 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
|
|
||||||
* [no]ncq: Turn on or off NCQ.
|
* [no]ncq: Turn on or off NCQ.
|
||||||
|
|
||||||
|
* nohrst, nosrst, norst: suppress hard, soft
|
||||||
|
and both resets.
|
||||||
|
|
||||||
If there are multiple matching configurations changing
|
If there are multiple matching configurations changing
|
||||||
the same attribute, the last one is used.
|
the same attribute, the last one is used.
|
||||||
|
|
||||||
|
|
|
@ -486,6 +486,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||||
{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
|
{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
|
||||||
{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
|
{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
|
||||||
{ PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
|
{ PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
|
||||||
|
|
||||||
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
|
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
|
||||||
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
@ -575,9 +577,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||||
{ PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */
|
{ PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */
|
||||||
|
|
||||||
/* SiS */
|
/* SiS */
|
||||||
{ PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp }, /* SiS 966 */
|
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
|
||||||
{ PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp }, /* SiS 968 */
|
{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 968 */
|
||||||
{ PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp }, /* SiS 968 */
|
{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
|
||||||
|
|
||||||
/* Marvell */
|
/* Marvell */
|
||||||
{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
|
{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
|
||||||
|
|
|
@ -275,6 +275,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
|
||||||
{ 0x8086, 0x3a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
|
{ 0x8086, 0x3a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
|
||||||
/* SATA Controller IDE (ICH10) */
|
/* SATA Controller IDE (ICH10) */
|
||||||
{ 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
|
{ 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
|
||||||
|
/* SATA Controller IDE (PCH) */
|
||||||
|
{ 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
|
||||||
|
/* SATA Controller IDE (PCH) */
|
||||||
|
{ 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
|
||||||
|
/* SATA Controller IDE (PCH) */
|
||||||
|
{ 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
|
||||||
|
/* SATA Controller IDE (PCH) */
|
||||||
|
{ 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
|
||||||
|
|
||||||
{ } /* terminate list */
|
{ } /* terminate list */
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,6 +104,7 @@ struct ata_force_param {
|
||||||
unsigned long xfer_mask;
|
unsigned long xfer_mask;
|
||||||
unsigned int horkage_on;
|
unsigned int horkage_on;
|
||||||
unsigned int horkage_off;
|
unsigned int horkage_off;
|
||||||
|
unsigned int lflags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ata_force_ent {
|
struct ata_force_ent {
|
||||||
|
@ -196,22 +197,23 @@ void ata_force_cbl(struct ata_port *ap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_force_spd_limit - force SATA spd limit according to libata.force
|
* ata_force_link_limits - force link limits according to libata.force
|
||||||
* @link: ATA link of interest
|
* @link: ATA link of interest
|
||||||
*
|
*
|
||||||
* Force SATA spd limit according to libata.force and whine about
|
* Force link flags and SATA spd limit according to libata.force
|
||||||
* it. When only the port part is specified (e.g. 1:), the limit
|
* and whine about it. When only the port part is specified
|
||||||
* applies to all links connected to both the host link and all
|
* (e.g. 1:), the limit applies to all links connected to both
|
||||||
* fan-out ports connected via PMP. If the device part is
|
* the host link and all fan-out ports connected via PMP. If the
|
||||||
* specified as 0 (e.g. 1.00:), it specifies the first fan-out
|
* device part is specified as 0 (e.g. 1.00:), it specifies the
|
||||||
* link not the host link. Device number 15 always points to the
|
* first fan-out link not the host link. Device number 15 always
|
||||||
* host link whether PMP is attached or not.
|
* points to the host link whether PMP is attached or not.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* EH context.
|
* EH context.
|
||||||
*/
|
*/
|
||||||
static void ata_force_spd_limit(struct ata_link *link)
|
static void ata_force_link_limits(struct ata_link *link)
|
||||||
{
|
{
|
||||||
|
bool did_spd = false;
|
||||||
int linkno, i;
|
int linkno, i;
|
||||||
|
|
||||||
if (ata_is_host_link(link))
|
if (ata_is_host_link(link))
|
||||||
|
@ -228,13 +230,22 @@ static void ata_force_spd_limit(struct ata_link *link)
|
||||||
if (fe->device != -1 && fe->device != linkno)
|
if (fe->device != -1 && fe->device != linkno)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!fe->param.spd_limit)
|
/* only honor the first spd limit */
|
||||||
continue;
|
if (!did_spd && fe->param.spd_limit) {
|
||||||
|
|
||||||
link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
|
link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
|
||||||
ata_link_printk(link, KERN_NOTICE,
|
ata_link_printk(link, KERN_NOTICE,
|
||||||
"FORCE: PHY spd limit set to %s\n", fe->param.name);
|
"FORCE: PHY spd limit set to %s\n",
|
||||||
return;
|
fe->param.name);
|
||||||
|
did_spd = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* let lflags stack */
|
||||||
|
if (fe->param.lflags) {
|
||||||
|
link->flags |= fe->param.lflags;
|
||||||
|
ata_link_printk(link, KERN_NOTICE,
|
||||||
|
"FORCE: link flag 0x%x forced -> 0x%x\n",
|
||||||
|
fe->param.lflags, link->flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3277,7 +3288,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
||||||
dev->dma_mode = ata_xfer_mask2mode(dma_mask);
|
dev->dma_mode = ata_xfer_mask2mode(dma_mask);
|
||||||
|
|
||||||
found = 1;
|
found = 1;
|
||||||
if (dev->dma_mode != 0xff)
|
if (ata_dma_enabled(dev))
|
||||||
used_dma = 1;
|
used_dma = 1;
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
|
@ -3302,7 +3313,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
||||||
|
|
||||||
/* step 3: set host DMA timings */
|
/* step 3: set host DMA timings */
|
||||||
ata_link_for_each_dev(dev, link) {
|
ata_link_for_each_dev(dev, link) {
|
||||||
if (!ata_dev_enabled(dev) || dev->dma_mode == 0xff)
|
if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dev->xfer_mode = dev->dma_mode;
|
dev->xfer_mode = dev->dma_mode;
|
||||||
|
@ -5188,19 +5199,18 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
|
||||||
*/
|
*/
|
||||||
int sata_link_init_spd(struct ata_link *link)
|
int sata_link_init_spd(struct ata_link *link)
|
||||||
{
|
{
|
||||||
u32 scontrol;
|
|
||||||
u8 spd;
|
u8 spd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
|
rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
spd = (scontrol >> 4) & 0xf;
|
spd = (link->saved_scontrol >> 4) & 0xf;
|
||||||
if (spd)
|
if (spd)
|
||||||
link->hw_sata_spd_limit &= (1 << spd) - 1;
|
link->hw_sata_spd_limit &= (1 << spd) - 1;
|
||||||
|
|
||||||
ata_force_spd_limit(link);
|
ata_force_link_limits(link);
|
||||||
|
|
||||||
link->sata_spd_limit = link->hw_sata_spd_limit;
|
link->sata_spd_limit = link->hw_sata_spd_limit;
|
||||||
|
|
||||||
|
@ -5783,9 +5793,10 @@ static void ata_port_detach(struct ata_port *ap)
|
||||||
ata_port_wait_eh(ap);
|
ata_port_wait_eh(ap);
|
||||||
|
|
||||||
/* EH is now guaranteed to see UNLOADING - EH context belongs
|
/* EH is now guaranteed to see UNLOADING - EH context belongs
|
||||||
* to us. Disable all existing devices.
|
* to us. Restore SControl and disable all existing devices.
|
||||||
*/
|
*/
|
||||||
ata_port_for_each_link(link, ap) {
|
__ata_port_for_each_link(link, ap) {
|
||||||
|
sata_scr_write(link, SCR_CONTROL, link->saved_scontrol);
|
||||||
ata_link_for_each_dev(dev, link)
|
ata_link_for_each_dev(dev, link)
|
||||||
ata_dev_disable(dev);
|
ata_dev_disable(dev);
|
||||||
}
|
}
|
||||||
|
@ -5991,6 +6002,9 @@ static int __init ata_parse_force_one(char **cur,
|
||||||
{ "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
|
{ "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
|
||||||
{ "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
|
{ "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
|
||||||
{ "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) },
|
{ "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) },
|
||||||
|
{ "nohrst", .lflags = ATA_LFLAG_NO_HRST },
|
||||||
|
{ "nosrst", .lflags = ATA_LFLAG_NO_SRST },
|
||||||
|
{ "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
|
||||||
};
|
};
|
||||||
char *start = *cur, *p = *cur;
|
char *start = *cur, *p = *cur;
|
||||||
char *id, *val, *endp;
|
char *id, *val, *endp;
|
||||||
|
|
|
@ -2040,7 +2040,7 @@ static void ata_eh_link_report(struct ata_link *link)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ehc->i.serror)
|
if (ehc->i.serror)
|
||||||
ata_port_printk(ap, KERN_ERR,
|
ata_link_printk(link, KERN_ERR,
|
||||||
"SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",
|
"SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",
|
||||||
ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
|
ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
|
||||||
ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
|
ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
|
||||||
|
@ -2171,18 +2171,12 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ata_eh_followup_srst_needed(struct ata_link *link,
|
static int ata_eh_followup_srst_needed(struct ata_link *link,
|
||||||
int rc, int classify,
|
int rc, const unsigned int *classes)
|
||||||
const unsigned int *classes)
|
|
||||||
{
|
{
|
||||||
if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
|
if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
|
||||||
return 0;
|
return 0;
|
||||||
if (rc == -EAGAIN) {
|
if (rc == -EAGAIN)
|
||||||
if (classify)
|
|
||||||
return 1;
|
return 1;
|
||||||
rc = 0;
|
|
||||||
}
|
|
||||||
if (rc != 0)
|
|
||||||
return 0;
|
|
||||||
if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
|
if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2210,6 +2204,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||||
*/
|
*/
|
||||||
while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
|
while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
|
||||||
max_tries++;
|
max_tries++;
|
||||||
|
if (link->flags & ATA_LFLAG_NO_HRST)
|
||||||
|
hardreset = NULL;
|
||||||
|
if (link->flags & ATA_LFLAG_NO_SRST)
|
||||||
|
softreset = NULL;
|
||||||
|
|
||||||
now = jiffies;
|
now = jiffies;
|
||||||
deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
|
deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
|
||||||
|
@ -2247,10 +2245,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||||
ehc->i.action &= ~ATA_EH_RESET;
|
ehc->i.action &= ~ATA_EH_RESET;
|
||||||
if (hardreset) {
|
if (hardreset) {
|
||||||
reset = hardreset;
|
reset = hardreset;
|
||||||
ehc->i.action = ATA_EH_HARDRESET;
|
ehc->i.action |= ATA_EH_HARDRESET;
|
||||||
} else if (softreset) {
|
} else if (softreset) {
|
||||||
reset = softreset;
|
reset = softreset;
|
||||||
ehc->i.action = ATA_EH_SOFTRESET;
|
ehc->i.action |= ATA_EH_SOFTRESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prereset) {
|
if (prereset) {
|
||||||
|
@ -2305,9 +2303,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||||
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
|
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
|
||||||
|
|
||||||
rc = ata_do_reset(link, reset, classes, deadline);
|
rc = ata_do_reset(link, reset, classes, deadline);
|
||||||
|
if (rc && rc != -EAGAIN)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
if (reset == hardreset &&
|
if (reset == hardreset &&
|
||||||
ata_eh_followup_srst_needed(link, rc, classify, classes)) {
|
ata_eh_followup_srst_needed(link, rc, classes)) {
|
||||||
/* okay, let's do follow-up softreset */
|
/* okay, let's do follow-up softreset */
|
||||||
reset = softreset;
|
reset = softreset;
|
||||||
|
|
||||||
|
@ -2322,10 +2322,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||||
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
|
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
|
||||||
rc = ata_do_reset(link, reset, classes, deadline);
|
rc = ata_do_reset(link, reset, classes, deadline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -EAGAIN can happen if we skipped followup SRST */
|
|
||||||
if (rc && rc != -EAGAIN)
|
|
||||||
goto fail;
|
|
||||||
} else {
|
} else {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
ata_link_printk(link, KERN_INFO, "no reset method "
|
ata_link_printk(link, KERN_INFO, "no reset method "
|
||||||
|
|
|
@ -181,7 +181,7 @@ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
|
||||||
|
|
||||||
if (adev != acpi->last) {
|
if (adev != acpi->last) {
|
||||||
pacpi_set_piomode(ap, adev);
|
pacpi_set_piomode(ap, adev);
|
||||||
if (adev->dma_mode)
|
if (ata_dma_enabled(adev))
|
||||||
pacpi_set_dmamode(ap, adev);
|
pacpi_set_dmamode(ap, adev);
|
||||||
acpi->last = adev;
|
acpi->last = adev;
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ static void atiixp_bmdma_start(struct ata_queued_cmd *qc)
|
||||||
u16 tmp16;
|
u16 tmp16;
|
||||||
|
|
||||||
pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
|
pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
|
||||||
if (adev->dma_mode >= XFER_UDMA_0)
|
if (ata_using_udma(adev))
|
||||||
tmp16 |= (1 << dn);
|
tmp16 |= (1 << dn);
|
||||||
else
|
else
|
||||||
tmp16 &= ~(1 << dn);
|
tmp16 &= ~(1 << dn);
|
||||||
|
|
|
@ -149,10 +149,10 @@ static unsigned int cs5530_qc_issue(struct ata_queued_cmd *qc)
|
||||||
struct ata_device *prev = ap->private_data;
|
struct ata_device *prev = ap->private_data;
|
||||||
|
|
||||||
/* See if the DMA settings could be wrong */
|
/* See if the DMA settings could be wrong */
|
||||||
if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
|
if (ata_dma_enabled(adev) && adev != prev && prev != NULL) {
|
||||||
/* Maybe, but do the channels match MWDMA/UDMA ? */
|
/* Maybe, but do the channels match MWDMA/UDMA ? */
|
||||||
if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
|
if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
|
||||||
(adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
|
(ata_using_udma(prev) && !ata_using_udma(adev)))
|
||||||
/* Switch the mode bits */
|
/* Switch the mode bits */
|
||||||
cs5530_set_dmamode(ap, adev);
|
cs5530_set_dmamode(ap, adev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -606,7 +606,7 @@ static void it821x_display_disk(int n, u8 *buf)
|
||||||
{
|
{
|
||||||
unsigned char id[41];
|
unsigned char id[41];
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
char *mtype;
|
char *mtype = "";
|
||||||
char mbuf[8];
|
char mbuf[8];
|
||||||
char *cbl = "(40 wire cable)";
|
char *cbl = "(40 wire cable)";
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc)
|
||||||
|
|
||||||
if (adev != ap->private_data) {
|
if (adev != ap->private_data) {
|
||||||
oldpiix_set_piomode(ap, adev);
|
oldpiix_set_piomode(ap, adev);
|
||||||
if (adev->dma_mode)
|
if (ata_dma_enabled(adev))
|
||||||
oldpiix_set_dmamode(ap, adev);
|
oldpiix_set_dmamode(ap, adev);
|
||||||
}
|
}
|
||||||
return ata_sff_qc_issue(qc);
|
return ata_sff_qc_issue(qc);
|
||||||
|
|
|
@ -167,10 +167,10 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
|
||||||
struct ata_device *prev = ap->private_data;
|
struct ata_device *prev = ap->private_data;
|
||||||
|
|
||||||
/* See if the DMA settings could be wrong */
|
/* See if the DMA settings could be wrong */
|
||||||
if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
|
if (ata_dma_enabled(adev) && adev != prev && prev != NULL) {
|
||||||
/* Maybe, but do the channels match MWDMA/UDMA ? */
|
/* Maybe, but do the channels match MWDMA/UDMA ? */
|
||||||
if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
|
if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
|
||||||
(adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
|
(ata_using_udma(prev) && !ata_using_udma(adev)))
|
||||||
/* Switch the mode bits */
|
/* Switch the mode bits */
|
||||||
sc1200_set_dmamode(ap, adev);
|
sc1200_set_dmamode(ap, adev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,7 +324,7 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* via_ata_sff_tf_load - send taskfile registers to host controller
|
* via_tf_load - send taskfile registers to host controller
|
||||||
* @ap: Port to which output is sent
|
* @ap: Port to which output is sent
|
||||||
* @tf: ATA taskfile register set
|
* @tf: ATA taskfile register set
|
||||||
*
|
*
|
||||||
|
@ -334,52 +334,16 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||||
* will reset the device register after changing the IEN bit on
|
* will reset the device register after changing the IEN bit on
|
||||||
* ctl register
|
* ctl register
|
||||||
*/
|
*/
|
||||||
static void via_ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
||||||
{
|
{
|
||||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
struct ata_taskfile tmp_tf;
|
||||||
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
|
|
||||||
|
|
||||||
if (tf->ctl != ap->last_ctl) {
|
if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) {
|
||||||
iowrite8(tf->ctl, ioaddr->ctl_addr);
|
tmp_tf = *tf;
|
||||||
iowrite8(tf->device, ioaddr->device_addr);
|
tmp_tf.flags |= ATA_TFLAG_DEVICE;
|
||||||
ap->last_ctl = tf->ctl;
|
tf = &tmp_tf;
|
||||||
ata_wait_idle(ap);
|
|
||||||
}
|
}
|
||||||
|
ata_sff_tf_load(ap, tf);
|
||||||
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
|
|
||||||
iowrite8(tf->hob_feature, ioaddr->feature_addr);
|
|
||||||
iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
|
|
||||||
iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
|
|
||||||
iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
|
|
||||||
iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
|
|
||||||
VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
|
|
||||||
tf->hob_feature,
|
|
||||||
tf->hob_nsect,
|
|
||||||
tf->hob_lbal,
|
|
||||||
tf->hob_lbam,
|
|
||||||
tf->hob_lbah);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_addr) {
|
|
||||||
iowrite8(tf->feature, ioaddr->feature_addr);
|
|
||||||
iowrite8(tf->nsect, ioaddr->nsect_addr);
|
|
||||||
iowrite8(tf->lbal, ioaddr->lbal_addr);
|
|
||||||
iowrite8(tf->lbam, ioaddr->lbam_addr);
|
|
||||||
iowrite8(tf->lbah, ioaddr->lbah_addr);
|
|
||||||
VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
|
|
||||||
tf->feature,
|
|
||||||
tf->nsect,
|
|
||||||
tf->lbal,
|
|
||||||
tf->lbam,
|
|
||||||
tf->lbah);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tf->flags & ATA_TFLAG_DEVICE) {
|
|
||||||
iowrite8(tf->device, ioaddr->device_addr);
|
|
||||||
VPRINTK("device 0x%X\n", tf->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
ata_wait_idle(ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct scsi_host_template via_sht = {
|
static struct scsi_host_template via_sht = {
|
||||||
|
@ -392,13 +356,12 @@ static struct ata_port_operations via_port_ops = {
|
||||||
.set_piomode = via_set_piomode,
|
.set_piomode = via_set_piomode,
|
||||||
.set_dmamode = via_set_dmamode,
|
.set_dmamode = via_set_dmamode,
|
||||||
.prereset = via_pre_reset,
|
.prereset = via_pre_reset,
|
||||||
.sff_tf_load = via_ata_tf_load,
|
.sff_tf_load = via_tf_load,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ata_port_operations via_port_ops_noirq = {
|
static struct ata_port_operations via_port_ops_noirq = {
|
||||||
.inherits = &via_port_ops,
|
.inherits = &via_port_ops,
|
||||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||||
.sff_tf_load = via_ata_tf_load,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1134,30 +1134,16 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
|
||||||
if (ap->nr_active_links == 0)
|
if (ap->nr_active_links == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
|
|
||||||
/*
|
/*
|
||||||
* The port is operating in host queuing mode (EDMA).
|
* The port is operating in host queuing mode (EDMA) with NCQ
|
||||||
* It can accomodate a new qc if the qc protocol
|
* enabled, allow multiple NCQ commands. EDMA also allows
|
||||||
* is compatible with the current host queue mode.
|
* queueing multiple DMA commands but libata core currently
|
||||||
|
* doesn't allow it.
|
||||||
*/
|
*/
|
||||||
if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) {
|
if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
|
||||||
/*
|
(pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
|
||||||
* The host queue (EDMA) is in NCQ mode.
|
|
||||||
* If the new qc is also an NCQ command,
|
|
||||||
* then allow the new qc.
|
|
||||||
*/
|
|
||||||
if (qc->tf.protocol == ATA_PROT_NCQ)
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* The host queue (EDMA) is in non-NCQ, DMA mode.
|
|
||||||
* If the new qc is also a non-NCQ, DMA command,
|
|
||||||
* then allow the new qc.
|
|
||||||
*/
|
|
||||||
if (qc->tf.protocol == ATA_PROT_DMA)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ATA_DEFER_PORT;
|
return ATA_DEFER_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3036,7 +3022,8 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
|
||||||
break;
|
break;
|
||||||
case chip_soc:
|
case chip_soc:
|
||||||
hpriv->ops = &mv_soc_ops;
|
hpriv->ops = &mv_soc_ops;
|
||||||
hp_flags |= MV_HP_FLAG_SOC | MV_HP_ERRATA_60X1C0;
|
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
|
||||||
|
MV_HP_ERRATA_60X1C0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -163,6 +163,7 @@ enum {
|
||||||
ATA_DEV_NONE = 9, /* no device */
|
ATA_DEV_NONE = 9, /* no device */
|
||||||
|
|
||||||
/* struct ata_link flags */
|
/* struct ata_link flags */
|
||||||
|
ATA_LFLAG_NO_HRST = (1 << 1), /* avoid hardreset */
|
||||||
ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */
|
ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */
|
||||||
ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */
|
ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */
|
||||||
ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */
|
ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */
|
||||||
|
@ -646,6 +647,7 @@ struct ata_link {
|
||||||
|
|
||||||
unsigned int flags; /* ATA_LFLAG_xxx */
|
unsigned int flags; /* ATA_LFLAG_xxx */
|
||||||
|
|
||||||
|
u32 saved_scontrol; /* SControl on probe */
|
||||||
unsigned int hw_sata_spd_limit;
|
unsigned int hw_sata_spd_limit;
|
||||||
unsigned int sata_spd_limit;
|
unsigned int sata_spd_limit;
|
||||||
unsigned int sata_spd; /* current SATA PHY speed */
|
unsigned int sata_spd; /* current SATA PHY speed */
|
||||||
|
@ -1427,6 +1429,28 @@ static inline unsigned long ata_deadline(unsigned long from_jiffies,
|
||||||
return from_jiffies + msecs_to_jiffies(timeout_msecs);
|
return from_jiffies + msecs_to_jiffies(timeout_msecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Don't open code these in drivers as there are traps. Firstly the range may
|
||||||
|
change in future hardware and specs, secondly 0xFF means 'no DMA' but is
|
||||||
|
> UDMA_0. Dyma ddreigiau */
|
||||||
|
|
||||||
|
static inline int ata_using_mwdma(struct ata_device *adev)
|
||||||
|
{
|
||||||
|
if (adev->dma_mode >= XFER_MW_DMA_0 && adev->dma_mode <= XFER_MW_DMA_4)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ata_using_udma(struct ata_device *adev)
|
||||||
|
{
|
||||||
|
if (adev->dma_mode >= XFER_UDMA_0 && adev->dma_mode <= XFER_UDMA_7)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ata_dma_enabled(struct ata_device *adev)
|
||||||
|
{
|
||||||
|
return (adev->dma_mode == 0xFF ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* PMP - drivers/ata/libata-pmp.c
|
* PMP - drivers/ata/libata-pmp.c
|
||||||
|
|
Loading…
Reference in a new issue