aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/sata_nv.c131
1 files changed, 81 insertions, 50 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 6cda12ba8122..b2d11f300c39 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -305,8 +305,8 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance);
305static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); 305static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
306static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); 306static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
307 307
308static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, 308static int nv_hardreset(struct ata_link *link, unsigned int *class,
309 unsigned long deadline); 309 unsigned long deadline);
310static void nv_nf2_freeze(struct ata_port *ap); 310static void nv_nf2_freeze(struct ata_port *ap);
311static void nv_nf2_thaw(struct ata_port *ap); 311static void nv_nf2_thaw(struct ata_port *ap);
312static void nv_ck804_freeze(struct ata_port *ap); 312static void nv_ck804_freeze(struct ata_port *ap);
@@ -406,49 +406,82 @@ static struct scsi_host_template nv_swncq_sht = {
406 .slave_configure = nv_swncq_slave_config, 406 .slave_configure = nv_swncq_slave_config,
407}; 407};
408 408
409static struct ata_port_operations nv_common_ops = { 409/*
410 * NV SATA controllers have various different problems with hardreset
411 * protocol depending on the specific controller and device.
412 *
413 * GENERIC:
414 *
415 * bko11195 reports that link doesn't come online after hardreset on
416 * generic nv's and there have been several other similar reports on
417 * linux-ide.
418 *
419 * bko12351#c23 reports that warmplug on MCP61 doesn't work with
420 * softreset.
421 *
422 * NF2/3:
423 *
424 * bko3352 reports nf2/3 controllers can't determine device signature
425 * reliably after hardreset. The following thread reports detection
426 * failure on cold boot with the standard debouncing timing.
427 *
428 * http://thread.gmane.org/gmane.linux.ide/34098
429 *
430 * bko12176 reports that hardreset fails to bring up the link during
431 * boot on nf2.
432 *
433 * CK804:
434 *
435 * For initial probing after boot and hot plugging, hardreset mostly
436 * works fine on CK804 but curiously, reprobing on the initial port
437 * by rescanning or rmmod/insmod fails to acquire the initial D2H Reg
438 * FIS in somewhat undeterministic way.
439 *
440 * SWNCQ:
441 *
442 * bko12351 reports that when SWNCQ is enabled, for hotplug to work,
443 * hardreset should be used and hardreset can't report proper
444 * signature, which suggests that mcp5x is closer to nf2 as long as
445 * reset quirkiness is concerned.
446 *
447 * bko12703 reports that boot probing fails for intel SSD with
448 * hardreset. Link fails to come online. Softreset works fine.
449 *
450 * The failures are varied but the following patterns seem true for
451 * all flavors.
452 *
453 * - Softreset during boot always works.
454 *
455 * - Hardreset during boot sometimes fails to bring up the link on
456 * certain comibnations and device signature acquisition is
457 * unreliable.
458 *
459 * - Hardreset is often necessary after hotplug.
460 *
461 * So, preferring softreset for boot probing and error handling (as
462 * hardreset might bring down the link) but using hardreset for
463 * post-boot probing should work around the above issues in most
464 * cases. Define nv_hardreset() which only kicks in for post-boot
465 * probing and use it for all variants.
466 */
467static struct ata_port_operations nv_generic_ops = {
410 .inherits = &ata_bmdma_port_ops, 468 .inherits = &ata_bmdma_port_ops,
411 .lost_interrupt = ATA_OP_NULL, 469 .lost_interrupt = ATA_OP_NULL,
412 .scr_read = nv_scr_read, 470 .scr_read = nv_scr_read,
413 .scr_write = nv_scr_write, 471 .scr_write = nv_scr_write,
472 .hardreset = nv_hardreset,
414}; 473};
415 474
416/* OSDL bz11195 reports that link doesn't come online after hardreset
417 * on generic nv's and there have been several other similar reports
418 * on linux-ide. Disable hardreset for generic nv's.
419 */
420static struct ata_port_operations nv_generic_ops = {
421 .inherits = &nv_common_ops,
422 .hardreset = ATA_OP_NULL,
423};
424
425/* nf2 is ripe with hardreset related problems.
426 *
427 * kernel bz#3352 reports nf2/3 controllers can't determine device
428 * signature reliably. The following thread reports detection failure
429 * on cold boot with the standard debouncing timing.
430 *
431 * http://thread.gmane.org/gmane.linux.ide/34098
432 *
433 * And bz#12176 reports that hardreset simply doesn't work on nf2.
434 * Give up on it and just don't do hardreset.
435 */
436static struct ata_port_operations nv_nf2_ops = { 475static struct ata_port_operations nv_nf2_ops = {
437 .inherits = &nv_generic_ops, 476 .inherits = &nv_generic_ops,
438 .freeze = nv_nf2_freeze, 477 .freeze = nv_nf2_freeze,
439 .thaw = nv_nf2_thaw, 478 .thaw = nv_nf2_thaw,
440}; 479};
441 480
442/* For initial probing after boot and hot plugging, hardreset mostly
443 * works fine on CK804 but curiously, reprobing on the initial port by
444 * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS
445 * in somewhat undeterministic way. Use noclassify hardreset.
446 */
447static struct ata_port_operations nv_ck804_ops = { 481static struct ata_port_operations nv_ck804_ops = {
448 .inherits = &nv_common_ops, 482 .inherits = &nv_generic_ops,
449 .freeze = nv_ck804_freeze, 483 .freeze = nv_ck804_freeze,
450 .thaw = nv_ck804_thaw, 484 .thaw = nv_ck804_thaw,
451 .hardreset = nv_noclassify_hardreset,
452 .host_stop = nv_ck804_host_stop, 485 .host_stop = nv_ck804_host_stop,
453}; 486};
454 487
@@ -476,19 +509,8 @@ static struct ata_port_operations nv_adma_ops = {
476 .host_stop = nv_adma_host_stop, 509 .host_stop = nv_adma_host_stop,
477}; 510};
478 511
479/* Kernel bz#12351 reports that when SWNCQ is enabled, for hotplug to
480 * work, hardreset should be used and hardreset can't report proper
481 * signature, which suggests that mcp5x is closer to nf2 as long as
482 * reset quirkiness is concerned. Define separate ops for mcp5x with
483 * nv_noclassify_hardreset().
484 */
485static struct ata_port_operations nv_mcp5x_ops = {
486 .inherits = &nv_common_ops,
487 .hardreset = nv_noclassify_hardreset,
488};
489
490static struct ata_port_operations nv_swncq_ops = { 512static struct ata_port_operations nv_swncq_ops = {
491 .inherits = &nv_mcp5x_ops, 513 .inherits = &nv_generic_ops,
492 514
493 .qc_defer = ata_std_qc_defer, 515 .qc_defer = ata_std_qc_defer,
494 .qc_prep = nv_swncq_qc_prep, 516 .qc_prep = nv_swncq_qc_prep,
@@ -557,7 +579,7 @@ static const struct ata_port_info nv_port_info[] = {
557 .pio_mask = NV_PIO_MASK, 579 .pio_mask = NV_PIO_MASK,
558 .mwdma_mask = NV_MWDMA_MASK, 580 .mwdma_mask = NV_MWDMA_MASK,
559 .udma_mask = NV_UDMA_MASK, 581 .udma_mask = NV_UDMA_MASK,
560 .port_ops = &nv_mcp5x_ops, 582 .port_ops = &nv_generic_ops,
561 .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht), 583 .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht),
562 }, 584 },
563 /* SWNCQ */ 585 /* SWNCQ */
@@ -1559,15 +1581,24 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
1559 return 0; 1581 return 0;
1560} 1582}
1561 1583
1562static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, 1584static int nv_hardreset(struct ata_link *link, unsigned int *class,
1563 unsigned long deadline) 1585 unsigned long deadline)
1564{ 1586{
1565 bool online; 1587 struct ata_eh_context *ehc = &link->eh_context;
1566 int rc;
1567 1588
1568 rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, 1589 /* Do hardreset iff it's post-boot probing, please read the
1569 &online, NULL); 1590 * comment above port ops for details.
1570 return online ? -EAGAIN : rc; 1591 */
1592 if (!(link->ap->pflags & ATA_PFLAG_LOADING) &&
1593 !ata_dev_enabled(link->device))
1594 sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
1595 NULL, NULL);
1596 else if (!(ehc->i.flags & ATA_EHI_QUIET))
1597 ata_link_printk(link, KERN_INFO,
1598 "nv: skipping hardreset on occupied port\n");
1599
1600 /* device signature acquisition is unreliable */
1601 return -EAGAIN;
1571} 1602}
1572 1603
1573static void nv_nf2_freeze(struct ata_port *ap) 1604static void nv_nf2_freeze(struct ata_port *ap)