pata_hpt366: fix cable detection,
[safe/jmp/linux-2.6] / drivers / ata / sata_nv.c
index 88fd4ae..6f14606 100644 (file)
@@ -307,6 +307,8 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 
 static void nv_nf2_freeze(struct ata_port *ap);
 static void nv_nf2_thaw(struct ata_port *ap);
+static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
+                           unsigned long deadline);
 static void nv_ck804_freeze(struct ata_port *ap);
 static void nv_ck804_thaw(struct ata_port *ap);
 static int nv_adma_slave_config(struct scsi_device *sdev);
@@ -403,28 +405,46 @@ static struct scsi_host_template nv_swncq_sht = {
        .slave_configure        = nv_swncq_slave_config,
 };
 
-static struct ata_port_operations nv_generic_ops = {
+static struct ata_port_operations nv_common_ops = {
        .inherits               = &ata_bmdma_port_ops,
-       .hardreset              = ATA_OP_NULL,
        .scr_read               = nv_scr_read,
        .scr_write              = nv_scr_write,
 };
 
+/* OSDL bz11195 reports that link doesn't come online after hardreset
+ * on generic nv's and there have been several other similar reports
+ * on linux-ide.  Disable hardreset for generic nv's.
+ */
+static struct ata_port_operations nv_generic_ops = {
+       .inherits               = &nv_common_ops,
+       .hardreset              = ATA_OP_NULL,
+};
+
+/* OSDL bz3352 reports that nf2/3 controllers can't determine device
+ * signature reliably.  Also, the following thread reports detection
+ * failure on cold boot with the standard debouncing timing.
+ *
+ * http://thread.gmane.org/gmane.linux.ide/34098
+ *
+ * Debounce with hotplug timing and request follow-up SRST.
+ */
 static struct ata_port_operations nv_nf2_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
        .freeze                 = nv_nf2_freeze,
        .thaw                   = nv_nf2_thaw,
+       .hardreset              = nv_nf2_hardreset,
 };
 
+/* CK804 finally gets hardreset right */
 static struct ata_port_operations nv_ck804_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
        .freeze                 = nv_ck804_freeze,
        .thaw                   = nv_ck804_thaw,
        .host_stop              = nv_ck804_host_stop,
 };
 
 static struct ata_port_operations nv_adma_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_ck804_ops,
 
        .check_atapi_dma        = nv_adma_check_atapi_dma,
        .sff_tf_read            = nv_adma_tf_read,
@@ -1534,6 +1554,17 @@ static void nv_nf2_thaw(struct ata_port *ap)
        iowrite8(mask, scr_addr + NV_INT_ENABLE);
 }
 
+static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
+                           unsigned long deadline)
+{
+       bool online;
+       int rc;
+
+       rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
+                                &online, NULL);
+       return online ? -EAGAIN : rc;
+}
+
 static void nv_ck804_freeze(struct ata_port *ap)
 {
        void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];