diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/sata_nv.c | 131 |
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); | |||
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, | 308 | static int nv_hardreset(struct ata_link *link, unsigned int *class, |
309 | unsigned long deadline); | 309 | unsigned long deadline); |
310 | static void nv_nf2_freeze(struct ata_port *ap); | 310 | static void nv_nf2_freeze(struct ata_port *ap); |
311 | static void nv_nf2_thaw(struct ata_port *ap); | 311 | static void nv_nf2_thaw(struct ata_port *ap); |
312 | static void nv_ck804_freeze(struct ata_port *ap); | 312 | static 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 | ||
409 | static 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 | */ | ||
467 | static 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 | */ | ||
420 | static 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 | */ | ||
436 | static struct ata_port_operations nv_nf2_ops = { | 475 | static 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 | */ | ||
447 | static struct ata_port_operations nv_ck804_ops = { | 481 | static 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 | */ | ||
485 | static struct ata_port_operations nv_mcp5x_ops = { | ||
486 | .inherits = &nv_common_ops, | ||
487 | .hardreset = nv_noclassify_hardreset, | ||
488 | }; | ||
489 | |||
490 | static struct ata_port_operations nv_swncq_ops = { | 512 | static 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 | ||
1562 | static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, | 1584 | static 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 | ||
1573 | static void nv_nf2_freeze(struct ata_port *ap) | 1604 | static void nv_nf2_freeze(struct ata_port *ap) |