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] ata_piix: Enable parallel scan
  sata_nv: use hardreset only for post-boot probing
  [libata] ahci: Restore SB600 SATA controller 64 bit DMA
  ata_piix: Remove stale comment
  ata_piix: Turn on hotplugging support for older chips
  ahci: misc cleanups for EM stuff
  [libata] get rid of ATA_MAX_QUEUE loop in ata_qc_complete_multiple() v2
  sata_sil: enable 32-bit PIO
  sata_sx4: speed up ECC initialization
  libata-sff: avoid byte swapping in ata_sff_data_xfer()
  [libata] ahci: use less error-prone array initializers
  • Loading branch information
Linus Torvalds committed Jun 11, 2009
2 parents c905959 + 517d3cc commit 6adc74b
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 93 deletions.
87 changes: 68 additions & 19 deletions drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
size_t size);
static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
ssize_t size);
#define MAX_SLOTS 8
#define MAX_RETRY 15

enum {
AHCI_PCI_BAR = 5,
Expand Down Expand Up @@ -231,6 +229,10 @@ enum {

ICH_MAP = 0x90, /* ICH MAP register */

/* em constants */
EM_MAX_SLOTS = 8,
EM_MAX_RETRY = 5,

/* em_ctl bits */
EM_CTL_RST = (1 << 9), /* Reset */
EM_CTL_TM = (1 << 8), /* Transmit Message */
Expand Down Expand Up @@ -282,8 +284,8 @@ struct ahci_port_priv {
unsigned int ncq_saw_dmas:1;
unsigned int ncq_saw_sdb:1;
u32 intr_mask; /* interrupts to enable */
struct ahci_em_priv em_priv[MAX_SLOTS];/* enclosure management info
* per PM slot */
/* enclosure management info per PM slot */
struct ahci_em_priv em_priv[EM_MAX_SLOTS];
};

static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
Expand Down Expand Up @@ -313,7 +315,6 @@ static void ahci_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
static int ahci_port_resume(struct ata_port *ap);
static void ahci_dev_config(struct ata_device *dev);
static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
u32 opts);
#ifdef CONFIG_PM
Expand Down Expand Up @@ -404,40 +405,39 @@ static struct ata_port_operations ahci_sb600_ops = {
#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)

static const struct ata_port_info ahci_port_info[] = {
/* board_ahci */
[board_ahci] =
{
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
/* board_ahci_vt8251 */
[board_ahci_vt8251] =
{
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_vt8251_ops,
},
/* board_ahci_ign_iferr */
[board_ahci_ign_iferr] =
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
/* board_ahci_sb600 */
[board_ahci_sb600] =
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
AHCI_HFLAG_SECT255),
AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_sb600_ops,
},
/* board_ahci_mv */
[board_ahci_mv] =
{
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
Expand All @@ -447,23 +447,23 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
/* board_ahci_sb700, for SB700 and SB800 */
[board_ahci_sb700] = /* for SB700 and SB800 */
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_sb600_ops,
},
/* board_ahci_mcp65 */
[board_ahci_mcp65] =
{
AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
/* board_ahci_nopmp */
[board_ahci_nopmp] =
{
AHCI_HFLAGS (AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
Expand Down Expand Up @@ -1141,12 +1141,12 @@ static void ahci_start_port(struct ata_port *ap)
emp = &pp->em_priv[link->pmp];

/* EM Transmit bit maybe busy during init */
for (i = 0; i < MAX_RETRY; i++) {
for (i = 0; i < EM_MAX_RETRY; i++) {
rc = ahci_transmit_led_message(ap,
emp->led_state,
4);
if (rc == -EBUSY)
udelay(100);
msleep(1);
else
break;
}
Expand Down Expand Up @@ -1340,7 +1340,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,

/* get the slot number from the message */
pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8;
if (pmp < MAX_SLOTS)
if (pmp < EM_MAX_SLOTS)
emp = &pp->em_priv[pmp];
else
return -EINVAL;
Expand Down Expand Up @@ -1408,7 +1408,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,

/* get the slot number from the message */
pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8;
if (pmp < MAX_SLOTS)
if (pmp < EM_MAX_SLOTS)
emp = &pp->em_priv[pmp];
else
return -EINVAL;
Expand Down Expand Up @@ -2584,6 +2584,51 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
}
}

/*
* SB600 ahci controller on ASUS M2A-VM can't do 64bit DMA with older
* BIOS. The oldest version known to be broken is 0901 and working is
* 1501 which was released on 2007-10-26. Force 32bit DMA on anything
* older than 1501. Please read bko#9412 for more info.
*/
static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev)
{
static const struct dmi_system_id sysids[] = {
{
.ident = "ASUS M2A-VM",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR,
"ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"),
},
},
{ }
};
const char *cutoff_mmdd = "10/26";
const char *date;
int year;

if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) ||
!dmi_check_system(sysids))
return false;

/*
* Argh.... both version and date are free form strings.
* Let's hope they're using the same date format across
* different versions.
*/
date = dmi_get_system_info(DMI_BIOS_DATE);
year = dmi_get_year(DMI_BIOS_DATE);
if (date && strlen(date) >= 10 && date[2] == '/' && date[5] == '/' &&
(year > 2007 ||
(year == 2007 && strncmp(date, cutoff_mmdd, 5) >= 0)))
return false;

dev_printk(KERN_WARNING, &pdev->dev, "ASUS M2A-VM: BIOS too old, "
"forcing 32bit DMA, update BIOS\n");

return true;
}

static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
{
static const struct dmi_system_id broken_systems[] = {
Expand Down Expand Up @@ -2744,6 +2789,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;

/* apply ASUS M2A_VM quirk */
if (ahci_asus_m2a_vm_32bit_only(pdev))
hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;

if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
pci_enable_msi(pdev);

Expand Down
11 changes: 5 additions & 6 deletions drivers/ata/ata_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* ICH8 Mobile PATA Controller */
{ 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },

/* NOTE: The following PCI ids must be kept in sync with the
* list in drivers/pci/quirks.c.
*/

/* SATA ports */

/* 82801EB (ICH5) */
{ 0x8086, 0x24d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
/* 82801EB (ICH5) */
Expand Down Expand Up @@ -1509,8 +1507,8 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");

/* no hotplugging support (FIXME) */
if (!in_module_init)
/* no hotplugging support for later devices (FIXME) */
if (!in_module_init && ent->driver_data >= ich5_sata)
return -ENODEV;

if (piix_broken_system_poweroff(pdev)) {
Expand Down Expand Up @@ -1591,6 +1589,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
host->ports[1]->mwdma_mask = 0;
host->ports[1]->udma_mask = 0;
}
host->flags |= ATA_HOST_PARALLEL_SCAN;

pci_set_master(pdev);
return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht);
Expand Down
11 changes: 5 additions & 6 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5031,7 +5031,6 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active)
{
int nr_done = 0;
u32 done_mask;
int i;

done_mask = ap->qc_active ^ qc_active;

Expand All @@ -5041,16 +5040,16 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active)
return -EINVAL;
}

for (i = 0; i < ATA_MAX_QUEUE; i++) {
while (done_mask) {
struct ata_queued_cmd *qc;
unsigned int tag = __ffs(done_mask);

if (!(done_mask & (1 << i)))
continue;

if ((qc = ata_qc_from_tag(ap, i))) {
qc = ata_qc_from_tag(ap, tag);
if (qc) {
ata_qc_complete(qc);
nr_done++;
}
done_mask &= ~(1 << tag);
}

return nr_done;
Expand Down
20 changes: 13 additions & 7 deletions drivers/ata/libata-sff.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,17 +727,23 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf,
else
iowrite16_rep(data_addr, buf, words);

/* Transfer trailing 1 byte, if any. */
/* Transfer trailing byte, if any. */
if (unlikely(buflen & 0x01)) {
__le16 align_buf[1] = { 0 };
unsigned char *trailing_buf = buf + buflen - 1;
unsigned char pad[2];

/* Point buf to the tail of buffer */
buf += buflen - 1;

/*
* Use io*16_rep() accessors here as well to avoid pointlessly
* swapping bytes to and fro on the big endian machines...
*/
if (rw == READ) {
align_buf[0] = cpu_to_le16(ioread16(data_addr));
memcpy(trailing_buf, align_buf, 1);
ioread16_rep(data_addr, pad, 1);
*buf = pad[0];
} else {
memcpy(align_buf, trailing_buf, 1);
iowrite16(le16_to_cpu(align_buf[0]), data_addr);
pad[0] = *buf;
iowrite16_rep(data_addr, pad, 1);
}
words++;
}
Expand Down
Loading

0 comments on commit 6adc74b

Please sign in to comment.