Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jgarzik/libata-dev

Pull libata updates from Jeff Garzik:

 1) AHCI regression fix.  A recent "make driver conform to spec" change
    broke on deployed hardware.  Make new behavior optional, rather than
    default, turning it on only for specific embedded platforms that
    need this.

    Everybody else runs in the famous "non conformant but working" mode.

 2) pata_cmd64x, pata_legacy cleanups

 3) new Intel SATA PCI IDs

 4) misc minor vendor feature additions

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  pata_cmd64x: implement sff_irq_check() method
  pata_cmd64x: implement sff_irq_clear() method
  pata_cmd64x: use interrupt status from MRDMODE register
  pata_cmd64x: turn string of *if* statements into *switch*
  drivers/ata/pata_mpc52xx.c: clean up error handling code
  ahci_platform: add STRICT_AHCI platform type
  ahci: move AHCI_HFLAGS() macro to ahci.h
  ahci: add AHCI_HFLAG_DELAY_ENGINE host flag
  sata_fsl: add support for interrupt coalsecing feature
  ata/pata_arasan_cf: Add Hibernation support
  pata_legacy: correctly mask recovery field for HT6560B
  ata_piix: IDE-mode SATA patch for Intel Lynx Point DeviceIDs
  ahci: AHCI-mode SATA patch for Intel Lynx Point DeviceIDs
  • Loading branch information
Linus Torvalds committed Mar 23, 2012
2 parents 7bfe0e6 + b8cec3c commit 90597b6
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 76 deletions.
10 changes: 8 additions & 2 deletions drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ static struct ata_port_operations ahci_p5wdh_ops = {
.hardreset = ahci_p5wdh_hardreset,
};

#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)

static const struct ata_port_info ahci_port_info[] = {
/* by features */
[board_ahci] =
Expand Down Expand Up @@ -261,6 +259,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */
{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point 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
6 changes: 6 additions & 0 deletions drivers/ata/ahci.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ enum {
PORT_FBS_EN = (1 << 0), /* Enable FBS */

/* hpriv->flags bits */

#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)

AHCI_HFLAG_NO_NCQ = (1 << 0),
AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */
AHCI_HFLAG_IGN_SERR_INTERNAL = (1 << 2), /* ignore SERR_INTERNAL */
Expand All @@ -210,6 +213,9 @@ enum {
AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */
AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */
AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */
AHCI_HFLAG_DELAY_ENGINE = (1 << 15), /* do not start engine on
port start (wait until
error-handling stage) */

/* ap->flags bits */

Expand Down
11 changes: 11 additions & 0 deletions drivers/ata/ahci_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
enum ahci_type {
AHCI, /* standard platform ahci */
IMX53_AHCI, /* ahci on i.mx53 */
STRICT_AHCI, /* delayed DMA engine start */
};

static struct platform_device_id ahci_devtype[] = {
Expand All @@ -35,6 +36,9 @@ static struct platform_device_id ahci_devtype[] = {
}, {
.name = "imx53-ahci",
.driver_data = IMX53_AHCI,
}, {
.name = "strict-ahci",
.driver_data = STRICT_AHCI,
}, {
/* sentinel */
}
Expand All @@ -56,6 +60,13 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_pmp_retry_srst_ops,
},
[STRICT_AHCI] = {
AHCI_HFLAGS (AHCI_HFLAG_DELAY_ENGINE),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
};

static struct scsi_host_template ahci_platform_sht = {
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 @@ -321,6 +321,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (Panther Point) */
{ 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
{ } /* terminate list */
};

Expand Down
5 changes: 5 additions & 0 deletions drivers/ata/libahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ static void ahci_power_down(struct ata_port *ap)

static void ahci_start_port(struct ata_port *ap)
{
struct ahci_host_priv *hpriv = ap->host->private_data;
struct ahci_port_priv *pp = ap->private_data;
struct ata_link *link;
struct ahci_em_priv *emp;
Expand All @@ -746,6 +747,10 @@ static void ahci_start_port(struct ata_port *ap)
/* enable FIS reception */
ahci_start_fis_rx(ap);

/* enable DMA */
if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE))
ahci_start_engine(ap);

/* turn on LEDs */
if (ap->flags & ATA_FLAG_EM) {
ata_for_each_link(link, ap, EDGE) {
Expand Down
12 changes: 4 additions & 8 deletions drivers/ata/pata_arasan_cf.c
Original file line number Diff line number Diff line change
Expand Up @@ -925,11 +925,10 @@ static int arasan_cf_suspend(struct device *dev)
struct ata_host *host = dev_get_drvdata(dev);
struct arasan_cf_dev *acdev = host->ports[0]->private_data;

if (acdev->dma_chan) {
if (acdev->dma_chan)
acdev->dma_chan->device->device_control(acdev->dma_chan,
DMA_TERMINATE_ALL, 0);
dma_release_channel(acdev->dma_chan);
}

cf_exit(acdev);
return ata_host_suspend(host, PMSG_SUSPEND);
}
Expand All @@ -945,10 +944,7 @@ static int arasan_cf_resume(struct device *dev)
return 0;
}

static const struct dev_pm_ops arasan_cf_pm_ops = {
.suspend = arasan_cf_suspend,
.resume = arasan_cf_resume,
};
static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume);
#endif

static struct platform_driver arasan_cf_driver = {
Expand All @@ -958,7 +954,7 @@ static struct platform_driver arasan_cf_driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &arasan_cf_pm_ops,
.pm = &arasan_cf_pm_ops,
#endif
},
};
Expand Down
147 changes: 116 additions & 31 deletions drivers/ata/pata_cmd64x.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* (C) 2005 Red Hat Inc
* Alan Cox <alan@lxorguk.ukuu.org.uk>
* (C) 2009-2010 Bartlomiej Zolnierkiewicz
* (C) 2012 MontaVista Software, LLC <source@mvista.com>
*
* Based upon
* linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002
Expand Down Expand Up @@ -32,7 +33,7 @@
#include <linux/libata.h>

#define DRV_NAME "pata_cmd64x"
#define DRV_VERSION "0.2.5"
#define DRV_VERSION "0.2.18"

/*
* CMD64x specific registers definition.
Expand Down Expand Up @@ -229,28 +230,85 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}

/**
* cmd648_dma_stop - DMA stop callback
* @qc: Command in progress
* cmd64x_sff_irq_check - check IDE interrupt
* @ap: ATA interface
*
* DMA has completed.
* Check IDE interrupt in CFR/ARTTIM23 registers.
*/

static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
static bool cmd64x_sff_irq_check(struct ata_port *ap)
{
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 dma_intr;
int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
int dma_reg = ap->port_no ? ARTTIM23 : CFR;
int irq_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
int irq_reg = ap->port_no ? ARTTIM23 : CFR;
u8 irq_stat;

ata_bmdma_stop(qc);
/* NOTE: reading the register should clear the interrupt */
pci_read_config_byte(pdev, irq_reg, &irq_stat);

return irq_stat & irq_mask;
}

/**
* cmd64x_sff_irq_clear - clear IDE interrupt
* @ap: ATA interface
*
* Clear IDE interrupt in CFR/ARTTIM23 and DMA status registers.
*/

static void cmd64x_sff_irq_clear(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int irq_reg = ap->port_no ? ARTTIM23 : CFR;
u8 irq_stat;

ata_bmdma_irq_clear(ap);

pci_read_config_byte(pdev, dma_reg, &dma_intr);
pci_write_config_byte(pdev, dma_reg, dma_intr | dma_mask);
/* Reading the register should be enough to clear the interrupt */
pci_read_config_byte(pdev, irq_reg, &irq_stat);
}

/**
* cmd646r1_dma_stop - DMA stop callback
* cmd648_sff_irq_check - check IDE interrupt
* @ap: ATA interface
*
* Check IDE interrupt in MRDMODE register.
*/

static bool cmd648_sff_irq_check(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long base = pci_resource_start(pdev, 4);
int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
u8 mrdmode = inb(base + 1);

return mrdmode & irq_mask;
}

/**
* cmd648_sff_irq_clear - clear IDE interrupt
* @ap: ATA interface
*
* Clear IDE interrupt in MRDMODE and DMA status registers.
*/

static void cmd648_sff_irq_clear(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long base = pci_resource_start(pdev, 4);
int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
u8 mrdmode;

ata_bmdma_irq_clear(ap);

/* Clear this port's interrupt bit (leaving the other port alone) */
mrdmode = inb(base + 1);
mrdmode &= ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1);
outb(mrdmode | irq_mask, base + 1);
}

/**
* cmd646r1_bmdma_stop - DMA stop callback
* @qc: Command in progress
*
* Stub for now while investigating the r1 quirk in the old driver.
Expand All @@ -273,18 +331,30 @@ static const struct ata_port_operations cmd64x_base_ops = {

static struct ata_port_operations cmd64x_port_ops = {
.inherits = &cmd64x_base_ops,
.sff_irq_check = cmd64x_sff_irq_check,
.sff_irq_clear = cmd64x_sff_irq_clear,
.cable_detect = ata_cable_40wire,
};

static struct ata_port_operations cmd646r1_port_ops = {
.inherits = &cmd64x_base_ops,
.sff_irq_check = cmd64x_sff_irq_check,
.sff_irq_clear = cmd64x_sff_irq_clear,
.bmdma_stop = cmd646r1_bmdma_stop,
.cable_detect = ata_cable_40wire,
};

static struct ata_port_operations cmd646r3_port_ops = {
.inherits = &cmd64x_base_ops,
.sff_irq_check = cmd648_sff_irq_check,
.sff_irq_clear = cmd648_sff_irq_clear,
.cable_detect = ata_cable_40wire,
};

static struct ata_port_operations cmd648_port_ops = {
.inherits = &cmd64x_base_ops,
.bmdma_stop = cmd648_bmdma_stop,
.sff_irq_check = cmd648_sff_irq_check,
.sff_irq_clear = cmd648_sff_irq_clear,
.cable_detect = cmd648_cable_detect,
};

Expand All @@ -306,7 +376,7 @@ static void cmd64x_fixup(struct pci_dev *pdev)

static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info cmd_info[6] = {
static const struct ata_port_info cmd_info[7] = {
{ /* CMD 643 - no UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
Expand All @@ -319,12 +389,18 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.mwdma_mask = ATA_MWDMA2,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with working UDMA */
{ /* CMD 646U with broken UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.port_ops = &cmd646r3_port_ops
},
{ /* CMD 646U2 with working UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &cmd64x_port_ops
.port_ops = &cmd646r3_port_ops
},
{ /* CMD 646 rev 1 */
.flags = ATA_FLAG_SLAVE_POSS,
Expand Down Expand Up @@ -368,21 +444,30 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (id->driver_data == 0) /* 643 */
ata_pci_bmdma_clear_simplex(pdev);

if (pdev->device == PCI_DEVICE_ID_CMD_646) {
/* Does UDMA work ? */
if (pdev->revision > 4) {
ppi[0] = &cmd_info[2];
ppi[1] = &cmd_info[2];
}
/* Early rev with other problems ? */
else if (pdev->revision == 1) {
if (pdev->device == PCI_DEVICE_ID_CMD_646)
switch (pdev->revision) {
/* UDMA works since rev 5 */
default:
ppi[0] = &cmd_info[3];
ppi[1] = &cmd_info[3];
}
/* revs 1,2 have no CNTRL_CH0 */
if (pdev->revision < 3)
break;
/* Interrupts in MRDMODE since rev 3 */
case 3:
case 4:
ppi[0] = &cmd_info[2];
ppi[1] = &cmd_info[2];
break;
/* Rev 1 with other problems? */
case 1:
ppi[0] = &cmd_info[4];
ppi[1] = &cmd_info[4];
/* FALL THRU */
/* Early revs have no CNTRL_CH0 */
case 2:
case 0:
cntrl_ch0_ok = 0;
}
break;
}

cmd64x_fixup(pdev);

Expand Down Expand Up @@ -423,8 +508,8 @@ static int cmd64x_reinit_one(struct pci_dev *pdev)
static const struct pci_device_id cmd64x[] = {
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 4 },
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 5 },
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 5 },
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 6 },

{ },
};
Expand Down
3 changes: 1 addition & 2 deletions drivers/ata/pata_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);

active = clamp_val(t.active, 2, 15);
recover = clamp_val(t.recover, 2, 16);
recover &= 0x15;
recover = clamp_val(t.recover, 2, 16) & 0x0F;

inb(0x3E6);
inb(0x3E6);
Expand Down
Loading

0 comments on commit 90597b6

Please sign in to comment.