]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/libata-core.c
libata: Spot bridge chips
[linux-2.6-omap-h63xx.git] / drivers / ata / libata-core.c
index 2be30c7a222687088f85605e3d92683691720a70..b81265d1e46936170be39687cddc780933aaafe9 100644 (file)
@@ -70,6 +70,7 @@ const unsigned long sata_deb_timing_long[]            = { 100, 2000, 5000 };
 static unsigned int ata_dev_init_params(struct ata_device *dev,
                                        u16 heads, u16 sectors);
 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
+static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable);
 static void ata_dev_xfermask(struct ata_device *dev);
 static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
@@ -86,6 +87,10 @@ int atapi_dmadir = 0;
 module_param(atapi_dmadir, int, 0444);
 MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)");
 
+int atapi_passthru16 = 1;
+module_param(atapi_passthru16, int, 0444);
+MODULE_PARM_DESC(atapi_passthru16, "Enable ATA_16 passthru for ATAPI devices; on by default (0=off, 1=on)");
+
 int libata_fua = 0;
 module_param_named(fua, libata_fua, int, 0444);
 MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
@@ -1614,6 +1619,9 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
  *     devices.  This function also issues ATA_CMD_INIT_DEV_PARAMS
  *     for pre-ATA4 drives.
  *
+ *     FIXME: ATA_CMD_ID_ATA is optional for early drives and right
+ *     now we abort if we hit that case. 
+ *
  *     LOCKING:
  *     Kernel thread context (may sleep)
  *
@@ -1741,10 +1749,13 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                /*
                 * The exact sequence expected by certain pre-ATA4 drives is:
                 * SRST RESET
-                * IDENTIFY
-                * INITIALIZE DEVICE PARAMETERS
+                * IDENTIFY (optional in early ATA)
+                * INITIALIZE DEVICE PARAMETERS (later IDE and ATA)
                 * anything else..
                 * Some drives were very specific about that exact sequence.
+                *
+                * Note that ATA4 says lba is mandatory so the second check
+                * shoud never trigger.
                 */
                if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
                        err_mask = ata_dev_init_params(dev, id[3], id[6]);
@@ -1977,6 +1988,22 @@ int ata_dev_configure(struct ata_device *dev)
                }
                dev->cdb_len = (unsigned int) rc;
 
+               /*
+                * check to see if this ATAPI device supports
+                * Asynchronous Notification
+                */
+               if ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id)) {
+                       int err;
+                       /* issue SET feature command to turn this on */
+                       err = ata_dev_set_AN(dev, SETFEATURES_SATA_ENABLE);
+                       if (err)
+                               ata_dev_printk(dev, KERN_ERR,
+                                               "unable to set AN, err %x\n",
+                                               err);
+                       else
+                               dev->flags |= ATA_DFLAG_AN;
+               }
+
                if (ata_id_cdb_intr(dev->id)) {
                        dev->flags |= ATA_DFLAG_CDB_INTR;
                        cdb_intr_string = ", CDB intr";
@@ -2156,6 +2183,17 @@ int ata_bus_probe(struct ata_port *ap)
        if (ap->ops->cable_detect)
                ap->cbl = ap->ops->cable_detect(ap);
 
+       /* We may have SATA bridge glue hiding here irrespective of the
+          reported cable types and sensed types */
+       ata_link_for_each_dev(dev, &ap->link) {
+               if (!ata_dev_enabled(dev))
+                       continue;
+               /* SATA drives indicate we have a bridge. We don't know which
+                  end of the link the bridge is which is a problem */
+               if (ata_id_is_sata(dev->id))
+                       ap->cbl = ATA_CBL_SATA;
+       }
+
        /* After the identify sequence we can now set up the devices. We do
           this in the normal order so that the user doesn't get confused */
 
@@ -2181,7 +2219,6 @@ int ata_bus_probe(struct ata_port *ap)
 
        /* no device present, disable port */
        ata_port_disable(ap);
-       ap->ops->port_disable(ap);
        return -ENODEV;
 
  fail:
@@ -2759,7 +2796,11 @@ static int ata_dev_set_mode(struct ata_device *dev)
        /* Old CFA may refuse this command, which is just fine */
        if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id))
                err_mask &= ~AC_ERR_DEV;
-
+       /* Some very old devices and some bad newer ones fail any kind of
+          SET_XFERMODE request but support PIO0-2 timings and no IORDY */
+       if (dev->xfer_shift == ATA_SHIFT_PIO && !ata_id_has_iordy(dev->id) &&
+                       dev->pio_mode <= XFER_PIO_2)
+               err_mask &= ~AC_ERR_DEV;
        if (err_mask) {
                ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
                               "(err_mask=0x%x)\n", err_mask);
@@ -3196,7 +3237,7 @@ void ata_bus_reset(struct ata_port *ap)
 
 err_out:
        ata_port_printk(ap, KERN_ERR, "disabling port\n");
-       ap->ops->port_disable(ap);
+       ata_port_disable(ap);
 
        DPRINTK("EXIT\n");
 }
@@ -3960,6 +4001,42 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
        return err_mask;
 }
 
+/**
+ *     ata_dev_set_AN - Issue SET FEATURES - SATA FEATURES
+ *     @dev: Device to which command will be sent
+ *     @enable: Whether to enable or disable the feature
+ *
+ *     Issue SET FEATURES - SATA FEATURES command to device @dev
+ *     on port @ap with sector count set to indicate Asynchronous
+ *     Notification feature
+ *
+ *     LOCKING:
+ *     PCI/etc. bus probe sem.
+ *
+ *     RETURNS:
+ *     0 on success, AC_ERR_* mask otherwise.
+ */
+static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable)
+{
+       struct ata_taskfile tf;
+       unsigned int err_mask;
+
+       /* set up set-features taskfile */
+       DPRINTK("set features - SATA features\n");
+
+       ata_tf_init(dev, &tf);
+       tf.command = ATA_CMD_SET_FEATURES;
+       tf.feature = enable;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+       tf.nsect = SATA_AN;
+
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+
+       DPRINTK("EXIT, err_mask=%x\n", err_mask);
+       return err_mask;
+}
+
 /**
  *     ata_dev_init_params - Issue INIT DEV PARAMS command
  *     @dev: Device to which command will be sent
@@ -4610,6 +4687,8 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc)
                        ata_pio_sector(qc);
        } else
                ata_pio_sector(qc);
+
+       ata_altstatus(qc->ap); /* flush */
 }
 
 /**
@@ -4784,6 +4863,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
        VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
 
        __atapi_pio_bytes(qc, bytes);
+       ata_altstatus(ap); /* flush */
 
        return;
 
@@ -4955,7 +5035,6 @@ fsm_start:
                         */
                        ap->hsm_task_state = HSM_ST;
                        ata_pio_sectors(qc);
-                       ata_altstatus(ap); /* flush */
                } else
                        /* send CDB */
                        atapi_send_cdb(ap, qc);
@@ -5036,7 +5115,6 @@ fsm_start:
 
                                if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
                                        ata_pio_sectors(qc);
-                                       ata_altstatus(ap);
                                        status = ata_wait_idle(ap);
                                }
 
@@ -5056,13 +5134,11 @@ fsm_start:
                        if (ap->hsm_task_state == HSM_ST_LAST &&
                            (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
                                /* all data read */
-                               ata_altstatus(ap);
                                status = ata_wait_idle(ap);
                                goto fsm_start;
                        }
                }
 
-               ata_altstatus(ap); /* flush */
                poll_next = 1;
                break;
 
@@ -5681,7 +5757,8 @@ idle_irq:
 
 #ifdef ATA_IRQ_TRAP
        if ((ap->stats.idle_irq % 1000) == 0) {
-               ap->ops->irq_ack(ap, 0); /* debug trap */
+               ata_chk_status(ap);
+               ap->ops->irq_clear(ap);
                ata_port_printk(ap, KERN_WARNING, "irq trap\n");
                return 1;
        }
@@ -5893,6 +5970,10 @@ int ata_flush_cache(struct ata_device *dev)
        else
                cmd = ATA_CMD_FLUSH;
 
+       /* This is wrong. On a failed flush we get back the LBA of the lost
+          sector and we should (assuming it wasn't aborted as unknown) issue
+          a further flush command to continue the writeback until it 
+          does not error */
        err_mask = ata_do_simple_cmd(dev, cmd);
        if (err_mask) {
                ata_dev_printk(dev, KERN_ERR, "failed to flush cache\n");
@@ -5912,6 +5993,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
 
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
+               struct ata_link *link;
 
                /* Previous resume operation might still be in
                 * progress.  Wait for PM_PENDING to clear.
@@ -5931,8 +6013,10 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
                }
 
                ap->pflags |= ATA_PFLAG_PM_PENDING;
-               ap->link.eh_info.action |= action;
-               ap->link.eh_info.flags |= ehi_flags;
+               __ata_port_for_each_link(link, ap) {
+                       link->eh_info.action |= action;
+                       link->eh_info.flags |= ehi_flags;
+               }
 
                ata_port_schedule_eh(ap);
 
@@ -6060,6 +6144,70 @@ void ata_dev_init(struct ata_device *dev)
        dev->udma_mask = UINT_MAX;
 }
 
+/**
+ *     ata_link_init - Initialize an ata_link structure
+ *     @ap: ATA port link is attached to
+ *     @link: Link structure to initialize
+ *     @pmp: Port multiplier port number
+ *
+ *     Initialize @link.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ */
+static void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
+{
+       int i;
+
+       /* clear everything except for devices */
+       memset(link, 0, offsetof(struct ata_link, device[0]));
+
+       link->ap = ap;
+       link->pmp = pmp;
+       link->active_tag = ATA_TAG_POISON;
+       link->hw_sata_spd_limit = UINT_MAX;
+
+       /* can't use iterator, ap isn't initialized yet */
+       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+               struct ata_device *dev = &link->device[i];
+
+               dev->link = link;
+               dev->devno = dev - link->device;
+               ata_dev_init(dev);
+       }
+}
+
+/**
+ *     sata_link_init_spd - Initialize link->sata_spd_limit
+ *     @link: Link to configure sata_spd_limit for
+ *
+ *     Initialize @link->[hw_]sata_spd_limit to the currently
+ *     configured value.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno on failure.
+ */
+static int sata_link_init_spd(struct ata_link *link)
+{
+       u32 scontrol, spd;
+       int rc;
+
+       rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
+       if (rc)
+               return rc;
+
+       spd = (scontrol >> 4) & 0xf;
+       if (spd)
+               link->hw_sata_spd_limit &= (1 << spd) - 1;
+
+       link->sata_spd_limit = link->hw_sata_spd_limit;
+
+       return 0;
+}
+
 /**
  *     ata_port_alloc - allocate and initialize basic ATA port resources
  *     @host: ATA host this allocated port belongs to
@@ -6075,7 +6223,6 @@ void ata_dev_init(struct ata_device *dev)
 struct ata_port *ata_port_alloc(struct ata_host *host)
 {
        struct ata_port *ap;
-       unsigned int i;
 
        DPRINTK("ENTER\n");
 
@@ -6090,9 +6237,6 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
        ap->ctl = ATA_DEVCTL_OBS;
        ap->host = host;
        ap->dev = host->dev;
-
-       ap->link.hw_sata_spd_limit = UINT_MAX;
-       ap->link.active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
 
 #if defined(ATA_VERBOSE_DEBUG)
@@ -6115,15 +6259,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
 
        ap->cbl = ATA_CBL_NONE;
 
-       ap->link.ap = ap;
-
-       /* can't use iterator, ap isn't initialized yet */
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->link.device[i];
-               dev->link = &ap->link;
-               dev->devno = i;
-               ata_dev_init(dev);
-       }
+       ata_link_init(ap, &ap->link, 0);
 
 #ifdef ATA_IRQ_TRAP
        ap->stats.unhandled_irq = 1;
@@ -6406,7 +6542,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
                int irq_line;
-               u32 scontrol;
                unsigned long xfer_mask;
 
                /* set SATA cable type if still unset */
@@ -6414,12 +6549,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
                        ap->cbl = ATA_CBL_SATA;
 
                /* init sata_spd_limit to the current value */
-               if (sata_scr_read(&ap->link, SCR_CONTROL, &scontrol) == 0) {
-                       int spd = (scontrol >> 4) & 0xf;
-                       if (spd)
-                               ap->link.hw_sata_spd_limit &= (1 << spd) - 1;
-               }
-               ap->link.sata_spd_limit = ap->link.hw_sata_spd_limit;
+               sata_link_init_spd(&ap->link);
 
                /* report the secondary IRQ for second channel legacy */
                irq_line = host->irq;
@@ -6558,6 +6688,7 @@ int ata_host_activate(struct ata_host *host, int irq,
 void ata_port_detach(struct ata_port *ap)
 {
        unsigned long flags;
+       struct ata_link *link;
        struct ata_device *dev;
 
        if (!ap->ops->error_handler)
@@ -6575,8 +6706,10 @@ void ata_port_detach(struct ata_port *ap)
         */
        spin_lock_irqsave(ap->lock, flags);
 
-       ata_link_for_each_dev(dev, &ap->link)
-               ata_dev_disable(dev);
+       ata_port_for_each_link(link, ap) {
+               ata_link_for_each_dev(dev, link)
+                       ata_dev_disable(dev);
+       }
 
        spin_unlock_irqrestore(ap->lock, flags);
 
@@ -6863,7 +6996,6 @@ static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
 }
 
 const struct ata_port_operations ata_dummy_port_ops = {
-       .port_disable           = ata_port_disable,
        .check_status           = ata_dummy_check_status,
        .check_altstatus        = ata_dummy_check_status,
        .dev_select             = ata_noop_dev_select,
@@ -7006,6 +7138,7 @@ EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
 EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
+EXPORT_SYMBOL_GPL(ata_link_abort);
 EXPORT_SYMBOL_GPL(ata_port_abort);
 EXPORT_SYMBOL_GPL(ata_port_freeze);
 EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
@@ -7014,9 +7147,6 @@ EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
 EXPORT_SYMBOL_GPL(ata_do_eh);
 EXPORT_SYMBOL_GPL(ata_irq_on);
-EXPORT_SYMBOL_GPL(ata_dummy_irq_on);
-EXPORT_SYMBOL_GPL(ata_irq_ack);
-EXPORT_SYMBOL_GPL(ata_dummy_irq_ack);
 EXPORT_SYMBOL_GPL(ata_dev_try_classify);
 
 EXPORT_SYMBOL_GPL(ata_cable_40wire);