]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/libata-acpi.c
firewire: Add sysfs attributes for config rom directory values.
[linux-2.6-omap-h63xx.git] / drivers / ata / libata-acpi.c
index 7b740fe1721b09f0ae1d4e33537b4394e45ba37c..d14a48e75f1b50414c3cbfba2afff82ce8c853d2 100644 (file)
@@ -294,9 +294,8 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
                return 0;
 
        if (ata_msg_probe(ap))
-               ata_dev_printk(atadev, KERN_DEBUG,
-                       "%s: ENTER: ap->id: %d, port#: %d\n",
-                       __FUNCTION__, ap->id, ap->port_no);
+               ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
+                              __FUNCTION__, ap->port_no);
 
        if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) {
                if (ata_msg_probe(ap))
@@ -456,6 +455,9 @@ static void taskfile_load_raw(struct ata_port *ap,
                                struct ata_device *atadev,
                                const struct taskfile_array *gtf)
 {
+       struct ata_taskfile tf;
+       unsigned int err;
+
        if (ata_msg_probe(ap))
                ata_dev_printk(atadev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
                        "%02x %02x %02x %02x %02x %02x %02x\n",
@@ -468,35 +470,25 @@ static void taskfile_load_raw(struct ata_port *ap,
            && (gtf->tfa[6] == 0))
                return;
 
-       if (ap->ops->qc_issue) {
-               struct ata_taskfile tf;
-               unsigned int err;
-
-               ata_tf_init(atadev, &tf);
-
-               /* convert gtf to tf */
-               tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
-               tf.protocol = atadev->class == ATA_DEV_ATAPI ?
-                       ATA_PROT_ATAPI_NODATA : ATA_PROT_NODATA;
-               tf.feature = gtf->tfa[0];       /* 0x1f1 */
-               tf.nsect   = gtf->tfa[1];       /* 0x1f2 */
-               tf.lbal    = gtf->tfa[2];       /* 0x1f3 */
-               tf.lbam    = gtf->tfa[3];       /* 0x1f4 */
-               tf.lbah    = gtf->tfa[4];       /* 0x1f5 */
-               tf.device  = gtf->tfa[5];       /* 0x1f6 */
-               tf.command = gtf->tfa[6];       /* 0x1f7 */
-
-               err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0);
-               if (err && ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_ERR,
-                               "%s: ata_exec_internal failed: %u\n",
-                               __FUNCTION__, err);
-       } else
-               if (ata_msg_warn(ap))
-                       ata_dev_printk(atadev, KERN_WARNING,
-                               "%s: SATA driver is missing qc_issue function"
-                               " entry points\n",
-                               __FUNCTION__);
+       ata_tf_init(atadev, &tf);
+
+       /* convert gtf to tf */
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
+       tf.protocol = atadev->class == ATA_DEV_ATAPI ?
+               ATA_PROT_ATAPI_NODATA : ATA_PROT_NODATA;
+       tf.feature = gtf->tfa[0];       /* 0x1f1 */
+       tf.nsect   = gtf->tfa[1];       /* 0x1f2 */
+       tf.lbal    = gtf->tfa[2];       /* 0x1f3 */
+       tf.lbam    = gtf->tfa[3];       /* 0x1f4 */
+       tf.lbah    = gtf->tfa[4];       /* 0x1f5 */
+       tf.device  = gtf->tfa[5];       /* 0x1f6 */
+       tf.command = gtf->tfa[6];       /* 0x1f7 */
+
+       err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0);
+       if (err && ata_msg_probe(ap))
+               ata_dev_printk(atadev, KERN_ERR,
+                       "%s: ata_exec_internal failed: %u\n",
+                       __FUNCTION__, err);
 }
 
 /**
@@ -521,9 +513,8 @@ static int do_drive_set_taskfiles(struct ata_port *ap,
        struct taskfile_array   *gtf;
 
        if (ata_msg_probe(ap))
-               ata_dev_printk(atadev, KERN_DEBUG,
-                       "%s: ENTER: ap->id: %d, port#: %d\n",
-                       __FUNCTION__, ap->id, ap->port_no);
+               ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
+                              __FUNCTION__, ap->port_no);
 
        if (noacpi || !(ap->cbl == ATA_CBL_SATA))
                return 0;
@@ -600,3 +591,97 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
        return ret;
 }
 
+/**
+ * ata_acpi_push_id - send Identify data to drive
+ * @ap: the ata_port for the drive
+ * @ix: drive index
+ *
+ * _SDD ACPI object: for SATA mode only
+ * Must be after Identify (Packet) Device -- uses its data
+ * ATM this function never returns a failure.  It is an optional
+ * method and if it fails for whatever reason, we should still
+ * just keep going.
+ */
+int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+{
+       acpi_handle                     handle;
+       acpi_integer                    pcidevfn;
+       int                             err;
+       struct device                   *dev = ap->host->dev;
+       struct ata_device               *atadev = &ap->device[ix];
+       u32                             dev_adr;
+       acpi_status                     status;
+       struct acpi_object_list         input;
+       union acpi_object               in_params[1];
+
+       if (noacpi)
+               return 0;
+
+       if (ata_msg_probe(ap))
+               ata_dev_printk(atadev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
+                              __FUNCTION__, ix, ap->port_no);
+
+       /* Don't continue if not a SATA device. */
+       if (!(ap->cbl == ATA_CBL_SATA)) {
+               if (ata_msg_probe(ap))
+                       ata_dev_printk(atadev, KERN_DEBUG,
+                               "%s: Not a SATA device\n", __FUNCTION__);
+               goto out;
+       }
+
+       /* Don't continue if device has no _ADR method.
+        * _SDD is intended for known motherboard devices. */
+       err = sata_get_dev_handle(dev, &handle, &pcidevfn);
+       if (err < 0) {
+               if (ata_msg_probe(ap))
+                       ata_dev_printk(atadev, KERN_DEBUG,
+                               "%s: sata_get_dev_handle failed (%d\n",
+                               __FUNCTION__, err);
+               goto out;
+       }
+
+       /* Get this drive's _ADR info, if not already known */
+       if (!atadev->obj_handle) {
+               dev_adr = SATA_ADR_RSVD;
+               err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev,
+                                       &dev_adr);
+               if (err < 0 || dev_adr == SATA_ADR_RSVD ||
+                       !atadev->obj_handle) {
+                       if (ata_msg_probe(ap))
+                               ata_dev_printk(atadev, KERN_DEBUG,
+                                       "%s: get_sata_adr failed: "
+                                       "err=%d, dev_adr=%u, obj_handle=0x%p\n",
+                                       __FUNCTION__, err, dev_adr,
+                                       atadev->obj_handle);
+                       goto out;
+               }
+       }
+
+       /* Give the drive Identify data to the drive via the _SDD method */
+       /* _SDD: set up input parameters */
+       input.count = 1;
+       input.pointer = in_params;
+       in_params[0].type = ACPI_TYPE_BUFFER;
+       in_params[0].buffer.length = sizeof(atadev->id[0]) * ATA_ID_WORDS;
+       in_params[0].buffer.pointer = (u8 *)atadev->id;
+       /* Output buffer: _SDD has no output */
+
+       /* It's OK for _SDD to be missing too. */
+       swap_buf_le16(atadev->id, ATA_ID_WORDS);
+       status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
+       swap_buf_le16(atadev->id, ATA_ID_WORDS);
+
+       err = ACPI_FAILURE(status) ? -EIO : 0;
+       if (err < 0) {
+               if (ata_msg_probe(ap))
+                       ata_dev_printk(atadev, KERN_DEBUG,
+                                      "%s _SDD error: status = 0x%x\n",
+                                      __FUNCTION__, status);
+       }
+
+       /* always return success */
+out:
+       return 0;
+}
+
+