Skip to content

Commit 3c32428

Browse files
htejunJeff Garzik
authored andcommitted
sata_nv: fix generic, nf2/3 detection regression
All three flavors of sata_nv's are different in how their hardreset behaves. * generic: Hardreset is not reliable. Link often doesn't come online after hardreset. * nf2/3: A little bit better - link comes online with longer debounce timing. However, nf2/3 can't reliable wait for the first D2H Register FIS, so it can't wait for device readiness or classify the device after hardreset. Follow-up SRST required. * ck804: Hardreset finally works. The core layer change to prefer hardreset and follow up changes exposed the above issues and caused various detection regressions for all three flavors. This patch, hopefully, fixes all the known issues and should make sata_nv error handling more reliable. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
1 parent 554d491 commit 3c32428

File tree

1 file changed

+25
-28
lines changed

1 file changed

+25
-28
lines changed

drivers/ata/sata_nv.c

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,10 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
307307

308308
static void nv_nf2_freeze(struct ata_port *ap);
309309
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);
310312
static void nv_ck804_freeze(struct ata_port *ap);
311313
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);
314314
static int nv_adma_slave_config(struct scsi_device *sdev);
315315
static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
316316
static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
@@ -405,17 +405,8 @@ static struct scsi_host_template nv_swncq_sht = {
405405
.slave_configure = nv_swncq_slave_config,
406406
};
407407

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-
*/
416408
static struct ata_port_operations nv_common_ops = {
417409
.inherits = &ata_bmdma_port_ops,
418-
.hardreset = nv_hardreset,
419410
.scr_read = nv_scr_read,
420411
.scr_write = nv_scr_write,
421412
};
@@ -429,12 +420,22 @@ static struct ata_port_operations nv_generic_ops = {
429420
.hardreset = ATA_OP_NULL,
430421
};
431422

423+
/* OSDL bz3352 reports that nf2/3 controllers can't determine device
424+
* signature reliably. Also, the following thread reports detection
425+
* failure on cold boot with the standard debouncing timing.
426+
*
427+
* http://thread.gmane.org/gmane.linux.ide/34098
428+
*
429+
* Debounce with hotplug timing and request follow-up SRST.
430+
*/
432431
static struct ata_port_operations nv_nf2_ops = {
433432
.inherits = &nv_common_ops,
434433
.freeze = nv_nf2_freeze,
435434
.thaw = nv_nf2_thaw,
435+
.hardreset = nv_nf2_hardreset,
436436
};
437437

438+
/* CK804 finally gets hardreset right */
438439
static struct ata_port_operations nv_ck804_ops = {
439440
.inherits = &nv_common_ops,
440441
.freeze = nv_ck804_freeze,
@@ -443,7 +444,7 @@ static struct ata_port_operations nv_ck804_ops = {
443444
};
444445

445446
static struct ata_port_operations nv_adma_ops = {
446-
.inherits = &nv_common_ops,
447+
.inherits = &nv_ck804_ops,
447448

448449
.check_atapi_dma = nv_adma_check_atapi_dma,
449450
.sff_tf_read = nv_adma_tf_read,
@@ -467,7 +468,7 @@ static struct ata_port_operations nv_adma_ops = {
467468
};
468469

469470
static struct ata_port_operations nv_swncq_ops = {
470-
.inherits = &nv_common_ops,
471+
.inherits = &nv_generic_ops,
471472

472473
.qc_defer = ata_std_qc_defer,
473474
.qc_prep = nv_swncq_qc_prep,
@@ -1553,6 +1554,17 @@ static void nv_nf2_thaw(struct ata_port *ap)
15531554
iowrite8(mask, scr_addr + NV_INT_ENABLE);
15541555
}
15551556

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+
15561568
static void nv_ck804_freeze(struct ata_port *ap)
15571569
{
15581570
void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
@@ -1605,21 +1617,6 @@ static void nv_mcp55_thaw(struct ata_port *ap)
16051617
ata_sff_thaw(ap);
16061618
}
16071619

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-
16231620
static void nv_adma_error_handler(struct ata_port *ap)
16241621
{
16251622
struct nv_adma_port_priv *pp = ap->private_data;

0 commit comments

Comments
 (0)