提交 8c022fdd 编写于 作者: L 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:
  pata-rb532-cf: remove set_irq_type from finish_io
  [libata] pata_via: support VX855, future chips whose IDE controller use 0x0571
  sata_mv: no longer experimental (v2)
  sata_mv: msi masking fix (v2)
  sata_mv: Properly initialize main irq mask
  sata_mv: remove bogus nsect restriction
  sata_mv: don't read hc_irq_cause
  sata_mv: fix 8-port timeouts on 508x/6081 chips
  sata_nv: fix MCP5x reset
  sata_nv: rename nv_nf2_hardreset()
  libata: set NODEV_HINT for 0x7f status
  libata-sff: fix incorrect EH message
...@@ -112,11 +112,11 @@ config ATA_PIIX ...@@ -112,11 +112,11 @@ config ATA_PIIX
If unsure, say N. If unsure, say N.
config SATA_MV config SATA_MV
tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)" tristate "Marvell SATA support"
depends on EXPERIMENTAL
help help
This option enables support for the Marvell Serial ATA family. This option enables support for the Marvell Serial ATA family.
Currently supports 88SX[56]0[48][01] chips. Currently supports 88SX[56]0[48][01] PCI(-X) chips,
as well as the newer [67]042 PCI-X/PCIe and SOC devices.
If unsure, say N. If unsure, say N.
......
...@@ -1322,7 +1322,7 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, ...@@ -1322,7 +1322,7 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
* condition. Mark hint. * condition. Mark hint.
*/ */
ata_ehi_push_desc(ehi, "ST-ATA: " ata_ehi_push_desc(ehi, "ST-ATA: "
"DRQ=1 with device error, " "DRQ=0 without device error, "
"dev_stat 0x%X", status); "dev_stat 0x%X", status);
qc->err_mask |= AC_ERR_HSM | qc->err_mask |= AC_ERR_HSM |
AC_ERR_NODEV_HINT; AC_ERR_NODEV_HINT;
...@@ -1358,6 +1358,16 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, ...@@ -1358,6 +1358,16 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
qc->err_mask |= AC_ERR_HSM; qc->err_mask |= AC_ERR_HSM;
} }
/* There are oddball controllers with
* status register stuck at 0x7f and
* lbal/m/h at zero which makes it
* pass all other presence detection
* mechanisms we have. Set NODEV_HINT
* for it. Kernel bz#7241.
*/
if (status == 0x7f)
qc->err_mask |= AC_ERR_NODEV_HINT;
/* ata_pio_sectors() might change the /* ata_pio_sectors() might change the
* state to HSM_ST_LAST. so, the state * state to HSM_ST_LAST. so, the state
* is changed after ata_pio_sectors(). * is changed after ata_pio_sectors().
......
...@@ -63,8 +63,6 @@ static inline void rb532_pata_finish_io(struct ata_port *ap) ...@@ -63,8 +63,6 @@ static inline void rb532_pata_finish_io(struct ata_port *ap)
ata_sff_sync might be sufficient. */ ata_sff_sync might be sufficient. */
ata_sff_dma_pause(ap); ata_sff_dma_pause(ap);
ndelay(RB500_CF_IO_DELAY); ndelay(RB500_CF_IO_DELAY);
set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
} }
static void rb532_pata_exec_command(struct ata_port *ap, static void rb532_pata_exec_command(struct ata_port *ap,
......
...@@ -86,6 +86,10 @@ enum { ...@@ -86,6 +86,10 @@ enum {
VIA_SATA_PATA = 0x800, /* SATA/PATA combined configuration */ VIA_SATA_PATA = 0x800, /* SATA/PATA combined configuration */
}; };
enum {
VIA_IDFLAG_SINGLE = (1 << 0), /* single channel controller) */
};
/* /*
* VIA SouthBridge chips. * VIA SouthBridge chips.
*/ */
...@@ -97,8 +101,12 @@ static const struct via_isa_bridge { ...@@ -97,8 +101,12 @@ static const struct via_isa_bridge {
u8 rev_max; u8 rev_max;
u16 flags; u16 flags;
} via_isa_bridges[] = { } via_isa_bridges[] = {
{ "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f,
VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
{ "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 | { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 |
VIA_BAD_AST | VIA_SATA_PATA }, VIA_BAD_AST | VIA_SATA_PATA },
{ "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f,
VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
...@@ -122,6 +130,8 @@ static const struct via_isa_bridge { ...@@ -122,6 +130,8 @@ static const struct via_isa_bridge {
{ "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
{ "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f,
VIA_UDMA_133 | VIA_BAD_AST },
{ NULL } { NULL }
}; };
...@@ -460,6 +470,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -460,6 +470,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version; static int printed_version;
u8 enable; u8 enable;
u32 timing; u32 timing;
unsigned long flags = id->driver_data;
int rc; int rc;
if (!printed_version++) if (!printed_version++)
...@@ -469,9 +480,13 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -469,9 +480,13 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc) if (rc)
return rc; return rc;
if (flags & VIA_IDFLAG_SINGLE)
ppi[1] = &ata_dummy_port_info;
/* To find out how the IDE will behave and what features we /* To find out how the IDE will behave and what features we
actually have to look at the bridge not the IDE controller */ actually have to look at the bridge not the IDE controller */
for (config = via_isa_bridges; config->id; config++) for (config = via_isa_bridges; config->id != PCI_DEVICE_ID_VIA_ANON;
config++)
if ((isa = pci_get_device(PCI_VENDOR_ID_VIA + if ((isa = pci_get_device(PCI_VENDOR_ID_VIA +
!!(config->flags & VIA_BAD_ID), !!(config->flags & VIA_BAD_ID),
config->id, NULL))) { config->id, NULL))) {
...@@ -482,10 +497,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -482,10 +497,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_dev_put(isa); pci_dev_put(isa);
} }
if (!config->id) {
printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n");
return -ENODEV;
}
pci_dev_put(isa); pci_dev_put(isa);
if (!(config->flags & VIA_NO_ENABLES)) { if (!(config->flags & VIA_NO_ENABLES)) {
...@@ -587,6 +598,7 @@ static const struct pci_device_id via[] = { ...@@ -587,6 +598,7 @@ static const struct pci_device_id via[] = {
{ PCI_VDEVICE(VIA, 0x1571), }, { PCI_VDEVICE(VIA, 0x1571), },
{ PCI_VDEVICE(VIA, 0x3164), }, { PCI_VDEVICE(VIA, 0x3164), },
{ PCI_VDEVICE(VIA, 0x5324), }, { PCI_VDEVICE(VIA, 0x5324), },
{ PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE },
{ }, { },
}; };
......
...@@ -33,10 +33,6 @@ ...@@ -33,10 +33,6 @@
* *
* --> ATAPI support (Marvell claims the 60xx/70xx chips can do it). * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it).
* *
* --> Investigate problems with PCI Message Signalled Interrupts (MSI).
*
* --> Cache frequently-accessed registers in mv_port_priv to reduce overhead.
*
* --> Develop a low-power-consumption strategy, and implement it. * --> Develop a low-power-consumption strategy, and implement it.
* *
* --> [Experiment, low priority] Investigate interrupt coalescing. * --> [Experiment, low priority] Investigate interrupt coalescing.
...@@ -72,7 +68,7 @@ ...@@ -72,7 +68,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "sata_mv" #define DRV_NAME "sata_mv"
#define DRV_VERSION "1.24" #define DRV_VERSION "1.25"
enum { enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */ /* BAR's are enumerated in terms of pci_resource_start() terms */
...@@ -351,8 +347,6 @@ enum { ...@@ -351,8 +347,6 @@ enum {
EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */
GEN_II_NCQ_MAX_SECTORS = 256, /* max sects/io on Gen2 w/NCQ */
/* Host private flags (hp_flags) */ /* Host private flags (hp_flags) */
MV_HP_FLAG_MSI = (1 << 0), MV_HP_FLAG_MSI = (1 << 0),
MV_HP_ERRATA_50XXB0 = (1 << 1), MV_HP_ERRATA_50XXB0 = (1 << 1),
...@@ -883,19 +877,15 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, ...@@ -883,19 +877,15 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
struct mv_host_priv *hpriv = ap->host->private_data; struct mv_host_priv *hpriv = ap->host->private_data;
int hardport = mv_hardport_from_port(ap->port_no); int hardport = mv_hardport_from_port(ap->port_no);
void __iomem *hc_mmio = mv_hc_base_from_port( void __iomem *hc_mmio = mv_hc_base_from_port(
mv_host_base(ap->host), hardport); mv_host_base(ap->host), ap->port_no);
u32 hc_irq_cause, ipending; u32 hc_irq_cause;
/* clear EDMA event indicators, if any */ /* clear EDMA event indicators, if any */
writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
/* clear EDMA interrupt indicator, if any */ /* clear pending irq events */
hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
ipending = (DEV_IRQ | DMA_IRQ) << hardport; writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
if (hc_irq_cause & ipending) {
writelfl(hc_irq_cause & ~ipending,
hc_mmio + HC_IRQ_CAUSE_OFS);
}
mv_edma_cfg(ap, want_ncq); mv_edma_cfg(ap, want_ncq);
...@@ -1099,20 +1089,12 @@ static void mv6_dev_config(struct ata_device *adev) ...@@ -1099,20 +1089,12 @@ static void mv6_dev_config(struct ata_device *adev)
* *
* Gen-II does not support NCQ over a port multiplier * Gen-II does not support NCQ over a port multiplier
* (no FIS-based switching). * (no FIS-based switching).
*
* We don't have hob_nsect when doing NCQ commands on Gen-II.
* See mv_qc_prep() for more info.
*/ */
if (adev->flags & ATA_DFLAG_NCQ) { if (adev->flags & ATA_DFLAG_NCQ) {
if (sata_pmp_attached(adev->link->ap)) { if (sata_pmp_attached(adev->link->ap)) {
adev->flags &= ~ATA_DFLAG_NCQ; adev->flags &= ~ATA_DFLAG_NCQ;
ata_dev_printk(adev, KERN_INFO, ata_dev_printk(adev, KERN_INFO,
"NCQ disabled for command-based switching\n"); "NCQ disabled for command-based switching\n");
} else if (adev->max_sectors > GEN_II_NCQ_MAX_SECTORS) {
adev->max_sectors = GEN_II_NCQ_MAX_SECTORS;
ata_dev_printk(adev, KERN_INFO,
"max_sectors limited to %u for NCQ\n",
adev->max_sectors);
} }
} }
} }
...@@ -1450,7 +1432,8 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) ...@@ -1450,7 +1432,8 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
* only 11 bytes...so we must pick and choose required * only 11 bytes...so we must pick and choose required
* registers based on the command. So, we drop feature and * registers based on the command. So, we drop feature and
* hob_feature for [RW] DMA commands, but they are needed for * hob_feature for [RW] DMA commands, but they are needed for
* NCQ. NCQ will drop hob_nsect. * NCQ. NCQ will drop hob_nsect, which is not needed there
* (nsect is used only for the tag; feat/hob_feat hold true nsect).
*/ */
switch (tf->command) { switch (tf->command) {
case ATA_CMD_READ: case ATA_CMD_READ:
...@@ -2214,9 +2197,15 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) ...@@ -2214,9 +2197,15 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
struct ata_host *host = dev_instance; struct ata_host *host = dev_instance;
struct mv_host_priv *hpriv = host->private_data; struct mv_host_priv *hpriv = host->private_data;
unsigned int handled = 0; unsigned int handled = 0;
int using_msi = hpriv->hp_flags & MV_HP_FLAG_MSI;
u32 main_irq_cause, pending_irqs; u32 main_irq_cause, pending_irqs;
spin_lock(&host->lock); spin_lock(&host->lock);
/* for MSI: block new interrupts while in here */
if (using_msi)
writel(0, hpriv->main_irq_mask_addr);
main_irq_cause = readl(hpriv->main_irq_cause_addr); main_irq_cause = readl(hpriv->main_irq_cause_addr);
pending_irqs = main_irq_cause & hpriv->main_irq_mask; pending_irqs = main_irq_cause & hpriv->main_irq_mask;
/* /*
...@@ -2230,6 +2219,11 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) ...@@ -2230,6 +2219,11 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
handled = mv_host_intr(host, pending_irqs); handled = mv_host_intr(host, pending_irqs);
} }
spin_unlock(&host->lock); spin_unlock(&host->lock);
/* for MSI: unmask; interrupt cause bits will retrigger now */
if (using_msi)
writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr);
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
...@@ -2821,8 +2815,7 @@ static void mv_eh_thaw(struct ata_port *ap) ...@@ -2821,8 +2815,7 @@ static void mv_eh_thaw(struct ata_port *ap)
writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
/* clear pending irq events */ /* clear pending irq events */
hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
mv_enable_port_irqs(ap, ERR_IRQ); mv_enable_port_irqs(ap, ERR_IRQ);
...@@ -3075,6 +3068,9 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) ...@@ -3075,6 +3068,9 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS; hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS;
} }
/* initialize shadow irq mask with register's value */
hpriv->main_irq_mask = readl(hpriv->main_irq_mask_addr);
/* global interrupt mask: 0 == mask everything */ /* global interrupt mask: 0 == mask everything */
mv_set_main_irq_mask(host, ~0, 0); mv_set_main_irq_mask(host, ~0, 0);
...@@ -3430,9 +3426,9 @@ static int mv_pci_init_one(struct pci_dev *pdev, ...@@ -3430,9 +3426,9 @@ static int mv_pci_init_one(struct pci_dev *pdev,
if (rc) if (rc)
return rc; return rc;
/* Enable interrupts */ /* Enable message-switched interrupts, if requested */
if (msi && pci_enable_msi(pdev)) if (msi && pci_enable_msi(pdev) == 0)
pci_intx(pdev, 1); hpriv->hp_flags |= MV_HP_FLAG_MSI;
mv_dump_pci_cfg(pdev, 0x68); mv_dump_pci_cfg(pdev, 0x68);
mv_print_info(host); mv_print_info(host);
......
...@@ -305,10 +305,10 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); ...@@ -305,10 +305,10 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance);
static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline);
static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_freeze(struct ata_port *ap);
static void nv_nf2_thaw(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap);
static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline);
static void nv_ck804_freeze(struct ata_port *ap); static void nv_ck804_freeze(struct ata_port *ap);
static void nv_ck804_thaw(struct ata_port *ap); static void nv_ck804_thaw(struct ata_port *ap);
static int nv_adma_slave_config(struct scsi_device *sdev); static int nv_adma_slave_config(struct scsi_device *sdev);
...@@ -352,6 +352,7 @@ enum nv_host_type ...@@ -352,6 +352,7 @@ enum nv_host_type
NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */ NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */
CK804, CK804,
ADMA, ADMA,
MCP5x,
SWNCQ, SWNCQ,
}; };
...@@ -363,10 +364,10 @@ static const struct pci_device_id nv_pci_tbl[] = { ...@@ -363,10 +364,10 @@ static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), SWNCQ }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), MCP5x },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), SWNCQ }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), MCP5x },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), SWNCQ }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), MCP5x },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), SWNCQ }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), MCP5x },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
...@@ -432,7 +433,7 @@ static struct ata_port_operations nv_nf2_ops = { ...@@ -432,7 +433,7 @@ static struct ata_port_operations nv_nf2_ops = {
.inherits = &nv_common_ops, .inherits = &nv_common_ops,
.freeze = nv_nf2_freeze, .freeze = nv_nf2_freeze,
.thaw = nv_nf2_thaw, .thaw = nv_nf2_thaw,
.hardreset = nv_nf2_hardreset, .hardreset = nv_noclassify_hardreset,
}; };
/* CK804 finally gets hardreset right */ /* CK804 finally gets hardreset right */
...@@ -467,8 +468,19 @@ static struct ata_port_operations nv_adma_ops = { ...@@ -467,8 +468,19 @@ static struct ata_port_operations nv_adma_ops = {
.host_stop = nv_adma_host_stop, .host_stop = nv_adma_host_stop,
}; };
/* Kernel bz#12351 reports that when SWNCQ is enabled, for hotplug to
* work, hardreset should be used and hardreset can't report proper
* signature, which suggests that mcp5x is closer to nf2 as long as
* reset quirkiness is concerned. Define separate ops for mcp5x with
* nv_noclassify_hardreset().
*/
static struct ata_port_operations nv_mcp5x_ops = {
.inherits = &nv_common_ops,
.hardreset = nv_noclassify_hardreset,
};
static struct ata_port_operations nv_swncq_ops = { static struct ata_port_operations nv_swncq_ops = {
.inherits = &nv_generic_ops, .inherits = &nv_mcp5x_ops,
.qc_defer = ata_std_qc_defer, .qc_defer = ata_std_qc_defer,
.qc_prep = nv_swncq_qc_prep, .qc_prep = nv_swncq_qc_prep,
...@@ -531,6 +543,15 @@ static const struct ata_port_info nv_port_info[] = { ...@@ -531,6 +543,15 @@ static const struct ata_port_info nv_port_info[] = {
.port_ops = &nv_adma_ops, .port_ops = &nv_adma_ops,
.private_data = NV_PI_PRIV(nv_adma_interrupt, &nv_adma_sht), .private_data = NV_PI_PRIV(nv_adma_interrupt, &nv_adma_sht),
}, },
/* MCP5x */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_mcp5x_ops,
.private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht),
},
/* SWNCQ */ /* SWNCQ */
{ {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
...@@ -1530,6 +1551,17 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) ...@@ -1530,6 +1551,17 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
return 0; return 0;
} }
static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
bool online;
int rc;
rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
&online, NULL);
return online ? -EAGAIN : rc;
}
static void nv_nf2_freeze(struct ata_port *ap) static void nv_nf2_freeze(struct ata_port *ap)
{ {
void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr; void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
...@@ -1554,17 +1586,6 @@ static void nv_nf2_thaw(struct ata_port *ap) ...@@ -1554,17 +1586,6 @@ static void nv_nf2_thaw(struct ata_port *ap)
iowrite8(mask, scr_addr + NV_INT_ENABLE); iowrite8(mask, scr_addr + NV_INT_ENABLE);
} }
static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
bool online;
int rc;
rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
&online, NULL);
return online ? -EAGAIN : rc;
}
static void nv_ck804_freeze(struct ata_port *ap) static void nv_ck804_freeze(struct ata_port *ap)
{ {
void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR]; void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
...@@ -2355,14 +2376,9 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2355,14 +2376,9 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (type == CK804 && adma_enabled) { if (type == CK804 && adma_enabled) {
dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n"); dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
type = ADMA; type = ADMA;
} } else if (type == MCP5x && swncq_enabled) {
dev_printk(KERN_NOTICE, &pdev->dev, "Using SWNCQ mode\n");
if (type == SWNCQ) { type = SWNCQ;
if (swncq_enabled)
dev_printk(KERN_NOTICE, &pdev->dev,
"Using SWNCQ mode\n");
else
type = GENERIC;
} }
ppi[0] = &nv_port_info[type]; ppi[0] = &nv_port_info[type];
......
...@@ -1357,6 +1357,7 @@ ...@@ -1357,6 +1357,7 @@
#define PCI_DEVICE_ID_VIA_8783_0 0x3208 #define PCI_DEVICE_ID_VIA_8783_0 0x3208
#define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_8237 0x3227
#define PCI_DEVICE_ID_VIA_8251 0x3287 #define PCI_DEVICE_ID_VIA_8251 0x3287
#define PCI_DEVICE_ID_VIA_8261 0x3402
#define PCI_DEVICE_ID_VIA_8237A 0x3337 #define PCI_DEVICE_ID_VIA_8237A 0x3337
#define PCI_DEVICE_ID_VIA_8237S 0x3372 #define PCI_DEVICE_ID_VIA_8237S 0x3372
#define PCI_DEVICE_ID_VIA_SATA_EIDE 0x5324 #define PCI_DEVICE_ID_VIA_SATA_EIDE 0x5324
...@@ -1366,10 +1367,13 @@ ...@@ -1366,10 +1367,13 @@
#define PCI_DEVICE_ID_VIA_CX700 0x8324 #define PCI_DEVICE_ID_VIA_CX700 0x8324
#define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581 #define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581
#define PCI_DEVICE_ID_VIA_VX800 0x8353 #define PCI_DEVICE_ID_VIA_VX800 0x8353
#define PCI_DEVICE_ID_VIA_VX855 0x8409
#define PCI_DEVICE_ID_VIA_8371_1 0x8391 #define PCI_DEVICE_ID_VIA_8371_1 0x8391
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598
#define PCI_DEVICE_ID_VIA_838X_1 0xB188 #define PCI_DEVICE_ID_VIA_838X_1 0xB188
#define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 #define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198
#define PCI_DEVICE_ID_VIA_C409_IDE 0XC409
#define PCI_DEVICE_ID_VIA_ANON 0xFFFF
#define PCI_VENDOR_ID_SIEMENS 0x110A #define PCI_VENDOR_ID_SIEMENS 0x110A
#define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102 #define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册