Skip to content

Commit

Permalink
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/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
  • Loading branch information
Linus Torvalds committed Aug 22, 2008
2 parents f7edd5f + 4ef2818 commit a7b354e
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 126 deletions.
3 changes: 3 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,9 @@ and is between 256 and 4096 characters. It is defined in the file

* [no]ncq: Turn on or off NCQ.

* nohrst, nosrst, norst: suppress hard, soft
and both resets.

If there are multiple matching configurations changing
the same attribute, the last one is used.

Expand Down
8 changes: 5 additions & 3 deletions drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
{ PCI_VDEVICE(INTEL, 0x3a05), 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 */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
Expand Down Expand Up @@ -575,9 +577,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */

/* SiS */
{ PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp }, /* SiS 966 */
{ PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp }, /* SiS 968 */
{ PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp }, /* SiS 968 */
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 968 */
{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */

/* Marvell */
{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
Expand Down
8 changes: 8 additions & 0 deletions drivers/ata/ata_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
/* SATA Controller IDE (ICH10) */
{ 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 */
};
Expand Down
60 changes: 37 additions & 23 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ struct ata_force_param {
unsigned long xfer_mask;
unsigned int horkage_on;
unsigned int horkage_off;
unsigned int lflags;
};

struct ata_force_ent {
Expand Down Expand Up @@ -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
*
* Force SATA spd limit according to libata.force and whine about
* it. When only the port part is specified (e.g. 1:), the limit
* applies to all links connected to both the host link and all
* fan-out ports connected via PMP. If the device part is
* specified as 0 (e.g. 1.00:), it specifies the first fan-out
* link not the host link. Device number 15 always points to the
* host link whether PMP is attached or not.
* Force link flags and SATA spd limit according to libata.force
* and whine about it. When only the port part is specified
* (e.g. 1:), the limit applies to all links connected to both
* the host link and all fan-out ports connected via PMP. If the
* device part is specified as 0 (e.g. 1.00:), it specifies the
* first fan-out link not the host link. Device number 15 always
* points to the host link whether PMP is attached or not.
*
* LOCKING:
* 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;

if (ata_is_host_link(link))
Expand All @@ -228,13 +230,22 @@ static void ata_force_spd_limit(struct ata_link *link)
if (fe->device != -1 && fe->device != linkno)
continue;

if (!fe->param.spd_limit)
continue;
/* only honor the first spd limit */
if (!did_spd && fe->param.spd_limit) {
link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
ata_link_printk(link, KERN_NOTICE,
"FORCE: PHY spd limit set to %s\n",
fe->param.name);
did_spd = true;
}

link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
ata_link_printk(link, KERN_NOTICE,
"FORCE: PHY spd limit set to %s\n", fe->param.name);
return;
/* 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);
}
}
}

Expand Down Expand Up @@ -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);

found = 1;
if (dev->dma_mode != 0xff)
if (ata_dma_enabled(dev))
used_dma = 1;
}
if (!found)
Expand All @@ -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 */
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;

dev->xfer_mode = dev->dma_mode;
Expand Down Expand Up @@ -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)
{
u32 scontrol;
u8 spd;
int rc;

rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol);
if (rc)
return rc;

spd = (scontrol >> 4) & 0xf;
spd = (link->saved_scontrol >> 4) & 0xf;
if (spd)
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;

Expand Down Expand Up @@ -5783,9 +5793,10 @@ static void ata_port_detach(struct ata_port *ap)
ata_port_wait_eh(ap);

/* 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_dev_disable(dev);
}
Expand Down Expand Up @@ -5991,6 +6002,9 @@ static int __init ata_parse_force_one(char **cur,
{ "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
{ "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
{ "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 *id, *val, *endp;
Expand Down
30 changes: 13 additions & 17 deletions drivers/ata/libata-eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -2040,7 +2040,7 @@ static void ata_eh_link_report(struct ata_link *link)
}

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",
ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
Expand Down Expand Up @@ -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,
int rc, int classify,
const unsigned int *classes)
int rc, const unsigned int *classes)
{
if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
return 0;
if (rc == -EAGAIN) {
if (classify)
return 1;
rc = 0;
}
if (rc != 0)
return 0;
if (rc == -EAGAIN)
return 1;
if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
return 1;
return 0;
Expand Down Expand Up @@ -2210,6 +2204,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
*/
while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
max_tries++;
if (link->flags & ATA_LFLAG_NO_HRST)
hardreset = NULL;
if (link->flags & ATA_LFLAG_NO_SRST)
softreset = NULL;

now = jiffies;
deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
Expand Down Expand Up @@ -2247,10 +2245,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
ehc->i.action &= ~ATA_EH_RESET;
if (hardreset) {
reset = hardreset;
ehc->i.action = ATA_EH_HARDRESET;
ehc->i.action |= ATA_EH_HARDRESET;
} else if (softreset) {
reset = softreset;
ehc->i.action = ATA_EH_SOFTRESET;
ehc->i.action |= ATA_EH_SOFTRESET;
}

if (prereset) {
Expand Down Expand Up @@ -2305,9 +2303,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;

rc = ata_do_reset(link, reset, classes, deadline);
if (rc && rc != -EAGAIN)
goto fail;

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 */
reset = softreset;

Expand All @@ -2322,10 +2322,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
rc = ata_do_reset(link, reset, classes, deadline);
}

/* -EAGAIN can happen if we skipped followup SRST */
if (rc && rc != -EAGAIN)
goto fail;
} else {
if (verbose)
ata_link_printk(link, KERN_INFO, "no reset method "
Expand Down
2 changes: 1 addition & 1 deletion drivers/ata/pata_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)

if (adev != acpi->last) {
pacpi_set_piomode(ap, adev);
if (adev->dma_mode)
if (ata_dma_enabled(adev))
pacpi_set_dmamode(ap, adev);
acpi->last = adev;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/ata/pata_atiixp.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ static void atiixp_bmdma_start(struct ata_queued_cmd *qc)
u16 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);
else
tmp16 &= ~(1 << dn);
Expand Down
6 changes: 3 additions & 3 deletions drivers/ata/pata_cs5530.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ static unsigned int cs5530_qc_issue(struct ata_queued_cmd *qc)
struct ata_device *prev = ap->private_data;

/* 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 ? */
if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
(adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
(ata_using_udma(prev) && !ata_using_udma(adev)))
/* Switch the mode bits */
cs5530_set_dmamode(ap, adev);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/ata/pata_it821x.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ static void it821x_display_disk(int n, u8 *buf)
{
unsigned char id[41];
int mode = 0;
char *mtype;
char *mtype = "";
char mbuf[8];
char *cbl = "(40 wire cable)";

Expand Down
2 changes: 1 addition & 1 deletion drivers/ata/pata_oldpiix.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc)

if (adev != ap->private_data) {
oldpiix_set_piomode(ap, adev);
if (adev->dma_mode)
if (ata_dma_enabled(adev))
oldpiix_set_dmamode(ap, adev);
}
return ata_sff_qc_issue(qc);
Expand Down
6 changes: 3 additions & 3 deletions drivers/ata/pata_sc1200.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,10 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
struct ata_device *prev = ap->private_data;

/* 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 ? */
if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
(adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
(ata_using_udma(prev) && !ata_using_udma(adev)))
/* Switch the mode bits */
sc1200_set_dmamode(ap, adev);
}
Expand Down
Loading

0 comments on commit a7b354e

Please sign in to comment.