Commit a7b354e8 authored by Linus Torvalds's avatar Linus Torvalds

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
parents f7edd5fb 4ef28185
...@@ -1074,6 +1074,9 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -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[] = { ...@@ -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[] = { ...@@ -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[] = { ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) {
iowrite8(tf->ctl, ioaddr->ctl_addr);
iowrite8(tf->device, ioaddr->device_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
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) { if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) {
iowrite8(tf->feature, ioaddr->feature_addr); tmp_tf = *tf;
iowrite8(tf->nsect, ioaddr->nsect_addr); tmp_tf.flags |= ATA_TFLAG_DEVICE;
iowrite8(tf->lbal, ioaddr->lbal_addr); tf = &tmp_tf;
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);
} }
ata_sff_tf_load(ap, tf);
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 = { ...@@ -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) ...@@ -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).
* It can accomodate a new qc if the qc protocol
* is compatible with the current host queue mode.
*/
if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) {
/* /*
* The host queue (EDMA) is in NCQ mode. * The port is operating in host queuing mode (EDMA) with NCQ
* If the new qc is also an NCQ command, * enabled, allow multiple NCQ commands. EDMA also allows
* then allow the new qc. * queueing multiple DMA commands but libata core currently
* doesn't allow it.
*/ */
if (qc->tf.protocol == ATA_PROT_NCQ) if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
(pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
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) ...@@ -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 { ...@@ -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 { ...@@ -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, ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment