diff options
Diffstat (limited to 'drivers/ata/sata_nv.c')
-rw-r--r-- | drivers/ata/sata_nv.c | 89 |
1 files changed, 56 insertions, 33 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 6f1460614325..55a8eed3f3a3 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -305,10 +305,10 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); | |||
305 | static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); | 305 | static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); |
306 | static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); | 306 | static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); |
307 | 307 | ||
308 | static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, | ||
309 | unsigned long deadline); | ||
308 | static void nv_nf2_freeze(struct ata_port *ap); | 310 | static void nv_nf2_freeze(struct ata_port *ap); |
309 | static void nv_nf2_thaw(struct ata_port *ap); | 311 | static void nv_nf2_thaw(struct ata_port *ap); |
310 | static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class, | ||
311 | unsigned long deadline); | ||
312 | static void nv_ck804_freeze(struct ata_port *ap); | 312 | static void nv_ck804_freeze(struct ata_port *ap); |
313 | static void nv_ck804_thaw(struct ata_port *ap); | 313 | static void nv_ck804_thaw(struct ata_port *ap); |
314 | static int nv_adma_slave_config(struct scsi_device *sdev); | 314 | static int nv_adma_slave_config(struct scsi_device *sdev); |
@@ -352,6 +352,7 @@ enum nv_host_type | |||
352 | NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */ | 352 | NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */ |
353 | CK804, | 353 | CK804, |
354 | ADMA, | 354 | ADMA, |
355 | MCP5x, | ||
355 | SWNCQ, | 356 | SWNCQ, |
356 | }; | 357 | }; |
357 | 358 | ||
@@ -363,10 +364,10 @@ static const struct pci_device_id nv_pci_tbl[] = { | |||
363 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 }, | 364 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 }, |
364 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 }, | 365 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 }, |
365 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 }, | 366 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 }, |
366 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), SWNCQ }, | 367 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), MCP5x }, |
367 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), SWNCQ }, | 368 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), MCP5x }, |
368 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), SWNCQ }, | 369 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), MCP5x }, |
369 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), SWNCQ }, | 370 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), MCP5x }, |
370 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, | 371 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, |
371 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, | 372 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, |
372 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, | 373 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, |
@@ -420,26 +421,33 @@ static struct ata_port_operations nv_generic_ops = { | |||
420 | .hardreset = ATA_OP_NULL, | 421 | .hardreset = ATA_OP_NULL, |
421 | }; | 422 | }; |
422 | 423 | ||
423 | /* OSDL bz3352 reports that nf2/3 controllers can't determine device | 424 | /* nf2 is ripe with hardreset related problems. |
424 | * signature reliably. Also, the following thread reports detection | 425 | * |
425 | * failure on cold boot with the standard debouncing timing. | 426 | * kernel bz#3352 reports nf2/3 controllers can't determine device |
427 | * signature reliably. The following thread reports detection failure | ||
428 | * on cold boot with the standard debouncing timing. | ||
426 | * | 429 | * |
427 | * http://thread.gmane.org/gmane.linux.ide/34098 | 430 | * http://thread.gmane.org/gmane.linux.ide/34098 |
428 | * | 431 | * |
429 | * Debounce with hotplug timing and request follow-up SRST. | 432 | * And bz#12176 reports that hardreset simply doesn't work on nf2. |
433 | * Give up on it and just don't do hardreset. | ||
430 | */ | 434 | */ |
431 | static struct ata_port_operations nv_nf2_ops = { | 435 | static struct ata_port_operations nv_nf2_ops = { |
432 | .inherits = &nv_common_ops, | 436 | .inherits = &nv_generic_ops, |
433 | .freeze = nv_nf2_freeze, | 437 | .freeze = nv_nf2_freeze, |
434 | .thaw = nv_nf2_thaw, | 438 | .thaw = nv_nf2_thaw, |
435 | .hardreset = nv_nf2_hardreset, | ||
436 | }; | 439 | }; |
437 | 440 | ||
438 | /* CK804 finally gets hardreset right */ | 441 | /* For initial probing after boot and hot plugging, hardreset mostly |
442 | * works fine on CK804 but curiously, reprobing on the initial port by | ||
443 | * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS | ||
444 | * in somewhat undeterministic way. Use noclassify hardreset. | ||
445 | */ | ||
439 | static struct ata_port_operations nv_ck804_ops = { | 446 | static struct ata_port_operations nv_ck804_ops = { |
440 | .inherits = &nv_common_ops, | 447 | .inherits = &nv_common_ops, |
441 | .freeze = nv_ck804_freeze, | 448 | .freeze = nv_ck804_freeze, |
442 | .thaw = nv_ck804_thaw, | 449 | .thaw = nv_ck804_thaw, |
450 | .hardreset = nv_noclassify_hardreset, | ||
443 | .host_stop = nv_ck804_host_stop, | 451 | .host_stop = nv_ck804_host_stop, |
444 | }; | 452 | }; |
445 | 453 | ||
@@ -467,8 +475,19 @@ static struct ata_port_operations nv_adma_ops = { | |||
467 | .host_stop = nv_adma_host_stop, | 475 | .host_stop = nv_adma_host_stop, |
468 | }; | 476 | }; |
469 | 477 | ||
478 | /* Kernel bz#12351 reports that when SWNCQ is enabled, for hotplug to | ||
479 | * work, hardreset should be used and hardreset can't report proper | ||
480 | * signature, which suggests that mcp5x is closer to nf2 as long as | ||
481 | * reset quirkiness is concerned. Define separate ops for mcp5x with | ||
482 | * nv_noclassify_hardreset(). | ||
483 | */ | ||
484 | static struct ata_port_operations nv_mcp5x_ops = { | ||
485 | .inherits = &nv_common_ops, | ||
486 | .hardreset = nv_noclassify_hardreset, | ||
487 | }; | ||
488 | |||
470 | static struct ata_port_operations nv_swncq_ops = { | 489 | static struct ata_port_operations nv_swncq_ops = { |
471 | .inherits = &nv_generic_ops, | 490 | .inherits = &nv_mcp5x_ops, |
472 | 491 | ||
473 | .qc_defer = ata_std_qc_defer, | 492 | .qc_defer = ata_std_qc_defer, |
474 | .qc_prep = nv_swncq_qc_prep, | 493 | .qc_prep = nv_swncq_qc_prep, |
@@ -531,6 +550,15 @@ static const struct ata_port_info nv_port_info[] = { | |||
531 | .port_ops = &nv_adma_ops, | 550 | .port_ops = &nv_adma_ops, |
532 | .private_data = NV_PI_PRIV(nv_adma_interrupt, &nv_adma_sht), | 551 | .private_data = NV_PI_PRIV(nv_adma_interrupt, &nv_adma_sht), |
533 | }, | 552 | }, |
553 | /* MCP5x */ | ||
554 | { | ||
555 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | ||
556 | .pio_mask = NV_PIO_MASK, | ||
557 | .mwdma_mask = NV_MWDMA_MASK, | ||
558 | .udma_mask = NV_UDMA_MASK, | ||
559 | .port_ops = &nv_mcp5x_ops, | ||
560 | .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht), | ||
561 | }, | ||
534 | /* SWNCQ */ | 562 | /* SWNCQ */ |
535 | { | 563 | { |
536 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 564 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
@@ -1530,6 +1558,17 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) | |||
1530 | return 0; | 1558 | return 0; |
1531 | } | 1559 | } |
1532 | 1560 | ||
1561 | static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, | ||
1562 | unsigned long deadline) | ||
1563 | { | ||
1564 | bool online; | ||
1565 | int rc; | ||
1566 | |||
1567 | rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, | ||
1568 | &online, NULL); | ||
1569 | return online ? -EAGAIN : rc; | ||
1570 | } | ||
1571 | |||
1533 | static void nv_nf2_freeze(struct ata_port *ap) | 1572 | static void nv_nf2_freeze(struct ata_port *ap) |
1534 | { | 1573 | { |
1535 | void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr; | 1574 | void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr; |
@@ -1554,17 +1593,6 @@ static void nv_nf2_thaw(struct ata_port *ap) | |||
1554 | iowrite8(mask, scr_addr + NV_INT_ENABLE); | 1593 | iowrite8(mask, scr_addr + NV_INT_ENABLE); |
1555 | } | 1594 | } |
1556 | 1595 | ||
1557 | static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class, | ||
1558 | unsigned long deadline) | ||
1559 | { | ||
1560 | bool online; | ||
1561 | int rc; | ||
1562 | |||
1563 | rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, | ||
1564 | &online, NULL); | ||
1565 | return online ? -EAGAIN : rc; | ||
1566 | } | ||
1567 | |||
1568 | static void nv_ck804_freeze(struct ata_port *ap) | 1596 | static void nv_ck804_freeze(struct ata_port *ap) |
1569 | { | 1597 | { |
1570 | void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR]; | 1598 | void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR]; |
@@ -2355,14 +2383,9 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2355 | if (type == CK804 && adma_enabled) { | 2383 | if (type == CK804 && adma_enabled) { |
2356 | dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n"); | 2384 | dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n"); |
2357 | type = ADMA; | 2385 | type = ADMA; |
2358 | } | 2386 | } else if (type == MCP5x && swncq_enabled) { |
2359 | 2387 | dev_printk(KERN_NOTICE, &pdev->dev, "Using SWNCQ mode\n"); | |
2360 | if (type == SWNCQ) { | 2388 | type = SWNCQ; |
2361 | if (swncq_enabled) | ||
2362 | dev_printk(KERN_NOTICE, &pdev->dev, | ||
2363 | "Using SWNCQ mode\n"); | ||
2364 | else | ||
2365 | type = GENERIC; | ||
2366 | } | 2389 | } |
2367 | 2390 | ||
2368 | ppi[0] = &nv_port_info[type]; | 2391 | ppi[0] = &nv_port_info[type]; |