diff options
| author | Tejun Heo <tj@kernel.org> | 2008-09-27 18:39:01 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-29 00:14:34 -0400 |
| commit | 4c1eb90a0908c0c60db2169dce08fb672e7582f1 (patch) | |
| tree | fbf71c285e390dcc714f633d00000f6792aeb681 | |
| parent | 6ef190cc92e33565accff6a320f0e7d90480bfe7 (diff) | |
sata_nv: reinstate nv_hardreset() for non generic controllers
Commit 2fd673ecf0378ddeeeb87b3605e50212e0c0ddc6 which tried to remove
hardreset for generic accidentally removed it for all flavors as all
others were inheriting from nv_generic_ops. This patch reinstates
nv_hardreset() and puts it into nv_common_ops which all flavors
inherit from. nv_generic_ops now inherits from nv_common_ops and
overrides .hardreset to ATA_OP_NULL.
While at it, explain why nv_hardreset and ATA_OP_NULL override are
necessary.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
| -rw-r--r-- | drivers/ata/sata_nv.c | 46 |
1 files changed, 40 insertions, 6 deletions
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; |
