diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ata_piix.c | 2 | ||||
-rw-r--r-- | drivers/ata/sata_inic162x.c | 3 | ||||
-rw-r--r-- | drivers/ata/sata_nv.c | 46 |
3 files changed, 43 insertions, 8 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index b1d08a8f5003..e6b4606e36b6 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -1499,7 +1499,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, | |||
1499 | * off. | 1499 | * off. |
1500 | */ | 1500 | */ |
1501 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2652) { | 1501 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2652) { |
1502 | int rc = piix_disable_ahci(pdev); | 1502 | rc = piix_disable_ahci(pdev); |
1503 | if (rc) | 1503 | if (rc) |
1504 | return rc; | 1504 | return rc; |
1505 | } | 1505 | } |
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 3ead02fe379e..5032c32fa505 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c | |||
@@ -96,6 +96,7 @@ enum { | |||
96 | PORT_SCR = 0x20, | 96 | PORT_SCR = 0x20, |
97 | 97 | ||
98 | /* HOST_CTL bits */ | 98 | /* HOST_CTL bits */ |
99 | HCTL_LEDEN = (1 << 3), /* enable LED operation */ | ||
99 | HCTL_IRQOFF = (1 << 8), /* global IRQ off */ | 100 | HCTL_IRQOFF = (1 << 8), /* global IRQ off */ |
100 | HCTL_FTHD0 = (1 << 10), /* fifo threshold 0 */ | 101 | HCTL_FTHD0 = (1 << 10), /* fifo threshold 0 */ |
101 | HCTL_FTHD1 = (1 << 11), /* fifo threshold 1*/ | 102 | HCTL_FTHD1 = (1 << 11), /* fifo threshold 1*/ |
@@ -540,7 +541,7 @@ static unsigned int inic_qc_issue(struct ata_queued_cmd *qc) | |||
540 | void __iomem *port_base = inic_port_base(ap); | 541 | void __iomem *port_base = inic_port_base(ap); |
541 | 542 | ||
542 | /* fire up the ADMA engine */ | 543 | /* fire up the ADMA engine */ |
543 | writew(HCTL_FTHD0, port_base + HOST_CTL); | 544 | writew(HCTL_FTHD0 | HCTL_LEDEN, port_base + HOST_CTL); |
544 | writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL); | 545 | writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL); |
545 | writeb(0, port_base + PORT_CPB_PTQFIFO); | 546 | writeb(0, port_base + PORT_CPB_PTQFIFO); |
546 | 547 | ||
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 1e1f3f3757ae..14601dc05e41 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -309,6 +309,8 @@ static void nv_nf2_freeze(struct ata_port *ap); | |||
309 | static void nv_nf2_thaw(struct ata_port *ap); | 309 | static void nv_nf2_thaw(struct ata_port *ap); |
310 | static void nv_ck804_freeze(struct ata_port *ap); | 310 | static void nv_ck804_freeze(struct ata_port *ap); |
311 | static void nv_ck804_thaw(struct ata_port *ap); | 311 | static void nv_ck804_thaw(struct ata_port *ap); |
312 | static int nv_hardreset(struct ata_link *link, unsigned int *class, | ||
313 | unsigned long deadline); | ||
312 | static int nv_adma_slave_config(struct scsi_device *sdev); | 314 | static int nv_adma_slave_config(struct scsi_device *sdev); |
313 | static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc); | 315 | static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc); |
314 | static void nv_adma_qc_prep(struct ata_queued_cmd *qc); | 316 | static void nv_adma_qc_prep(struct ata_queued_cmd *qc); |
@@ -403,28 +405,45 @@ static struct scsi_host_template nv_swncq_sht = { | |||
403 | .slave_configure = nv_swncq_slave_config, | 405 | .slave_configure = nv_swncq_slave_config, |
404 | }; | 406 | }; |
405 | 407 | ||
406 | static struct ata_port_operations nv_generic_ops = { | 408 | /* OSDL bz3352 reports that some nv controllers can't determine device |
409 | * signature reliably and nv_hardreset is implemented to work around | ||
410 | * the problem. This was reported on nf3 and it's unclear whether any | ||
411 | * other controllers are affected. However, the workaround has been | ||
412 | * applied to all variants and there isn't much to gain by trying to | ||
413 | * find out exactly which ones are affected at this point especially | ||
414 | * because NV has moved over to ahci for newer controllers. | ||
415 | */ | ||
416 | static struct ata_port_operations nv_common_ops = { | ||
407 | .inherits = &ata_bmdma_port_ops, | 417 | .inherits = &ata_bmdma_port_ops, |
408 | .hardreset = ATA_OP_NULL, | 418 | .hardreset = nv_hardreset, |
409 | .scr_read = nv_scr_read, | 419 | .scr_read = nv_scr_read, |
410 | .scr_write = nv_scr_write, | 420 | .scr_write = nv_scr_write, |
411 | }; | 421 | }; |
412 | 422 | ||
423 | /* OSDL bz11195 reports that link doesn't come online after hardreset | ||
424 | * on generic nv's and there have been several other similar reports | ||
425 | * on linux-ide. Disable hardreset for generic nv's. | ||
426 | */ | ||
427 | static struct ata_port_operations nv_generic_ops = { | ||
428 | .inherits = &nv_common_ops, | ||
429 | .hardreset = ATA_OP_NULL, | ||
430 | }; | ||
431 | |||
413 | static struct ata_port_operations nv_nf2_ops = { | 432 | static struct ata_port_operations nv_nf2_ops = { |
414 | .inherits = &nv_generic_ops, | 433 | .inherits = &nv_common_ops, |
415 | .freeze = nv_nf2_freeze, | 434 | .freeze = nv_nf2_freeze, |
416 | .thaw = nv_nf2_thaw, | 435 | .thaw = nv_nf2_thaw, |
417 | }; | 436 | }; |
418 | 437 | ||
419 | static struct ata_port_operations nv_ck804_ops = { | 438 | static struct ata_port_operations nv_ck804_ops = { |
420 | .inherits = &nv_generic_ops, | 439 | .inherits = &nv_common_ops, |
421 | .freeze = nv_ck804_freeze, | 440 | .freeze = nv_ck804_freeze, |
422 | .thaw = nv_ck804_thaw, | 441 | .thaw = nv_ck804_thaw, |
423 | .host_stop = nv_ck804_host_stop, | 442 | .host_stop = nv_ck804_host_stop, |
424 | }; | 443 | }; |
425 | 444 | ||
426 | static struct ata_port_operations nv_adma_ops = { | 445 | static struct ata_port_operations nv_adma_ops = { |
427 | .inherits = &nv_generic_ops, | 446 | .inherits = &nv_common_ops, |
428 | 447 | ||
429 | .check_atapi_dma = nv_adma_check_atapi_dma, | 448 | .check_atapi_dma = nv_adma_check_atapi_dma, |
430 | .sff_tf_read = nv_adma_tf_read, | 449 | .sff_tf_read = nv_adma_tf_read, |
@@ -448,7 +467,7 @@ static struct ata_port_operations nv_adma_ops = { | |||
448 | }; | 467 | }; |
449 | 468 | ||
450 | static struct ata_port_operations nv_swncq_ops = { | 469 | static struct ata_port_operations nv_swncq_ops = { |
451 | .inherits = &nv_generic_ops, | 470 | .inherits = &nv_common_ops, |
452 | 471 | ||
453 | .qc_defer = ata_std_qc_defer, | 472 | .qc_defer = ata_std_qc_defer, |
454 | .qc_prep = nv_swncq_qc_prep, | 473 | .qc_prep = nv_swncq_qc_prep, |
@@ -1586,6 +1605,21 @@ static void nv_mcp55_thaw(struct ata_port *ap) | |||
1586 | ata_sff_thaw(ap); | 1605 | ata_sff_thaw(ap); |
1587 | } | 1606 | } |
1588 | 1607 | ||
1608 | static int nv_hardreset(struct ata_link *link, unsigned int *class, | ||
1609 | unsigned long deadline) | ||
1610 | { | ||
1611 | int rc; | ||
1612 | |||
1613 | /* SATA hardreset fails to retrieve proper device signature on | ||
1614 | * some controllers. Request follow up SRST. For more info, | ||
1615 | * see http://bugzilla.kernel.org/show_bug.cgi?id=3352 | ||
1616 | */ | ||
1617 | rc = sata_sff_hardreset(link, class, deadline); | ||
1618 | if (rc) | ||
1619 | return rc; | ||
1620 | return -EAGAIN; | ||
1621 | } | ||
1622 | |||
1589 | static void nv_adma_error_handler(struct ata_port *ap) | 1623 | static void nv_adma_error_handler(struct ata_port *ap) |
1590 | { | 1624 | { |
1591 | struct nv_adma_port_priv *pp = ap->private_data; | 1625 | struct nv_adma_port_priv *pp = ap->private_data; |