]> err.no Git - linux-2.6/blobdiff - drivers/ata/libata-core.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
[linux-2.6] / drivers / ata / libata-core.c
index 733eb94d055e34420348a6edb65dbfb368728547..303fc0d2b978464dbf6d927a370f4cf743862b6b 100644 (file)
@@ -61,7 +61,6 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
-#include <asm/semaphore.h>
 #include <asm/byteorder.h>
 #include <linux/cdrom.h>
 
@@ -2127,6 +2126,13 @@ int ata_dev_configure(struct ata_device *dev)
        dev->horkage |= ata_dev_blacklisted(dev);
        ata_force_horkage(dev);
 
+       if (dev->horkage & ATA_HORKAGE_DISABLE) {
+               ata_dev_printk(dev, KERN_INFO,
+                              "unsupported device, disabling\n");
+               ata_dev_disable(dev);
+               return 0;
+       }
+
        /* let ACPI work its magic */
        rc = ata_acpi_on_devcfg(dev);
        if (rc)
@@ -2617,7 +2623,7 @@ void ata_port_probe(struct ata_port *ap)
  *     LOCKING:
  *     None.
  */
-void sata_print_link_status(struct ata_link *link)
+static void sata_print_link_status(struct ata_link *link)
 {
        u32 sstatus, scontrol, tmp;
 
@@ -2773,7 +2779,7 @@ static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol)
  *     RETURNS:
  *     1 if SATA spd configuration is needed, 0 otherwise.
  */
-int sata_set_spd_needed(struct ata_link *link)
+static int sata_set_spd_needed(struct ata_link *link)
 {
        u32 scontrol;
 
@@ -3378,7 +3384,7 @@ int ata_wait_ready(struct ata_link *link, unsigned long deadline,
  *     RETURNS:
  *     0 if @linke is ready before @deadline; otherwise, -errno.
  */
-extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
+int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
                                int (*check_ready)(struct ata_link *link))
 {
        msleep(ATA_WAIT_AFTER_RESET_MSECS);
@@ -3491,22 +3497,11 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
        if ((rc = sata_link_debounce(link, params, deadline)))
                return rc;
 
-       /* Clear SError.  PMP and some host PHYs require this to
-        * operate and clearing should be done before checking PHY
-        * online status to avoid race condition (hotplugging between
-        * link resume and status check).
-        */
+       /* clear SError, some PHYs require this even for SRST to work */
        if (!(rc = sata_scr_read(link, SCR_ERROR, &serror)))
                rc = sata_scr_write(link, SCR_ERROR, serror);
-       if (rc == 0 || rc == -EINVAL) {
-               unsigned long flags;
 
-               spin_lock_irqsave(link->ap->lock, flags);
-               link->eh_info.serror = 0;
-               spin_unlock_irqrestore(link->ap->lock, flags);
-               rc = 0;
-       }
-       return rc;
+       return rc != -EINVAL ? rc : 0;
 }
 
 /**
@@ -3654,9 +3649,13 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
        if (check_ready)
                rc = ata_wait_ready(link, deadline, check_ready);
  out:
-       if (rc && rc != -EAGAIN)
+       if (rc && rc != -EAGAIN) {
+               /* online is set iff link is online && reset succeeded */
+               if (online)
+                       *online = false;
                ata_link_printk(link, KERN_ERR,
                                "COMRESET failed (errno=%d)\n", rc);
+       }
        DPRINTK("EXIT, rc=%d\n", rc);
        return rc;
 }
@@ -3701,8 +3700,14 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class,
  */
 void ata_std_postreset(struct ata_link *link, unsigned int *classes)
 {
+       u32 serror;
+
        DPRINTK("ENTER\n");
 
+       /* reset complete, clear SError */
+       if (!sata_scr_read(link, SCR_ERROR, &serror))
+               sata_scr_write(link, SCR_ERROR, serror);
+
        /* print link status */
        sata_print_link_status(link);
 
@@ -3895,8 +3900,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "SAMSUNG CD-ROM SN-124", "N001",      ATA_HORKAGE_NODMA },
        { "Seagate STT20000A", NULL,            ATA_HORKAGE_NODMA },
        /* Odd clown on sil3726/4726 PMPs */
-       { "Config  Disk",       NULL,           ATA_HORKAGE_NODMA |
-                                               ATA_HORKAGE_SKIP_PM },
+       { "Config  Disk",       NULL,           ATA_HORKAGE_DISABLE },
 
        /* Weird ATAPI devices */
        { "TORiSAN DVD-ROM DRD-N216", NULL,     ATA_HORKAGE_MAX_SEC_128 },
@@ -3934,6 +3938,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 
        /* Devices which get the IVB wrong */
        { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
+       /* Maybe we should just blacklist TSSTcorp... */
+       { "TSSTcorp CDDVDW SH-S202H", "SB00",     ATA_HORKAGE_IVB, },
+       { "TSSTcorp CDDVDW SH-S202H", "SB01",     ATA_HORKAGE_IVB, },
        { "TSSTcorp CDDVDW SH-S202J", "SB00",     ATA_HORKAGE_IVB, },
        { "TSSTcorp CDDVDW SH-S202J", "SB01",     ATA_HORKAGE_IVB, },
        { "TSSTcorp CDDVDW SH-S202N", "SB00",     ATA_HORKAGE_IVB, },
@@ -4290,7 +4297,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 }
 
 /**
- *     ata_check_atapi_dma - Check whether ATAPI DMA can be supported
+ *     atapi_check_dma - Check whether ATAPI DMA can be supported
  *     @qc: Metadata associated with taskfile to check
  *
  *     Allow low-level driver to filter ATA PACKET commands, returning
@@ -4303,7 +4310,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
  *     RETURNS: 0 when ATAPI DMA can be used
  *               nonzero otherwise
  */
-int ata_check_atapi_dma(struct ata_queued_cmd *qc)
+int atapi_check_dma(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
 
@@ -5396,7 +5403,7 @@ static void ata_host_stop(struct device *gendev, void *res)
  */
 static void ata_finalize_port_ops(struct ata_port_operations *ops)
 {
-       static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+       static DEFINE_SPINLOCK(lock);
        const struct ata_port_operations *cur;
        void **begin = (void **)ops;
        void **end = (void **)&ops->inherits;
@@ -5614,7 +5621,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
                        spin_lock_irqsave(ap->lock, flags);
 
                        ehi->probe_mask |= ATA_ALL_DEVICES;
-                       ehi->action |= ATA_EH_RESET;
+                       ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
                        ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
 
                        ap->pflags &= ~ATA_PFLAG_INITIALIZING;
@@ -5647,7 +5654,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
                struct ata_port *ap = host->ports[i];
 
                ata_scsi_scan_host(ap, 1);
-               ata_lpm_schedule(ap, ap->pm_policy);
        }
 
        return 0;
@@ -6209,7 +6215,6 @@ EXPORT_SYMBOL_GPL(ata_host_detach);
 EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_qc_complete);
 EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);
-EXPORT_SYMBOL_GPL(sata_print_link_status);
 EXPORT_SYMBOL_GPL(atapi_cmd_type);
 EXPORT_SYMBOL_GPL(ata_tf_to_fis);
 EXPORT_SYMBOL_GPL(ata_tf_from_fis);
@@ -6291,6 +6296,7 @@ EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
 EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
 EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
+EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error);
 EXPORT_SYMBOL_GPL(ata_do_eh);
 EXPORT_SYMBOL_GPL(ata_std_error_handler);