aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-acpi.c96
-rw-r--r--drivers/ata/libata-core.c8
-rw-r--r--drivers/ata/libata.h5
3 files changed, 109 insertions, 0 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 7b740fe1721b..f2fd0dda70f2 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -600,3 +600,99 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
600 return ret; 600 return ret;
601} 601}
602 602
603/**
604 * ata_acpi_push_id - send Identify data to drive
605 * @ap: the ata_port for the drive
606 * @ix: drive index
607 *
608 * _SDD ACPI object: for SATA mode only
609 * Must be after Identify (Packet) Device -- uses its data
610 * ATM this function never returns a failure. It is an optional
611 * method and if it fails for whatever reason, we should still
612 * just keep going.
613 */
614int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
615{
616 acpi_handle handle;
617 acpi_integer pcidevfn;
618 int err;
619 struct device *dev = ap->host->dev;
620 struct ata_device *atadev = &ap->device[ix];
621 u32 dev_adr;
622 acpi_status status;
623 struct acpi_object_list input;
624 union acpi_object in_params[1];
625
626 if (noacpi)
627 return 0;
628
629 if (ata_msg_probe(ap))
630 ata_dev_printk(atadev, KERN_DEBUG,
631 "%s: ap->id: %d, ix = %d, port#: %d\n",
632 __FUNCTION__, ap->id, ix, ap->port_no);
633
634 /* Don't continue if not a SATA device. */
635 if (!(ap->cbl == ATA_CBL_SATA)) {
636 if (ata_msg_probe(ap))
637 ata_dev_printk(atadev, KERN_DEBUG,
638 "%s: Not a SATA device\n", __FUNCTION__);
639 goto out;
640 }
641
642 /* Don't continue if device has no _ADR method.
643 * _SDD is intended for known motherboard devices. */
644 err = sata_get_dev_handle(dev, &handle, &pcidevfn);
645 if (err < 0) {
646 if (ata_msg_probe(ap))
647 ata_dev_printk(atadev, KERN_DEBUG,
648 "%s: sata_get_dev_handle failed (%d\n",
649 __FUNCTION__, err);
650 goto out;
651 }
652
653 /* Get this drive's _ADR info, if not already known */
654 if (!atadev->obj_handle) {
655 dev_adr = SATA_ADR_RSVD;
656 err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev,
657 &dev_adr);
658 if (err < 0 || dev_adr == SATA_ADR_RSVD ||
659 !atadev->obj_handle) {
660 if (ata_msg_probe(ap))
661 ata_dev_printk(atadev, KERN_DEBUG,
662 "%s: get_sata_adr failed: "
663 "err=%d, dev_adr=%u, obj_handle=0x%p\n",
664 __FUNCTION__, err, dev_adr,
665 atadev->obj_handle);
666 goto out;
667 }
668 }
669
670 /* Give the drive Identify data to the drive via the _SDD method */
671 /* _SDD: set up input parameters */
672 input.count = 1;
673 input.pointer = in_params;
674 in_params[0].type = ACPI_TYPE_BUFFER;
675 in_params[0].buffer.length = sizeof(atadev->id[0] * ATA_ID_WORDS);
676 in_params[0].buffer.pointer = (u8 *)atadev->id;
677 /* Output buffer: _SDD has no output */
678
679 /* It's OK for _SDD to be missing too. */
680 swap_buf_le16(atadev->id, ATA_ID_WORDS);
681 status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
682 swap_buf_le16(atadev->id, ATA_ID_WORDS);
683
684 err = ACPI_FAILURE(status) ? -EIO : 0;
685 if (err < 0) {
686 if (ata_msg_probe(ap))
687 ata_dev_printk(atadev, KERN_DEBUG,
688 "ata%u(%u): %s _SDD error: status = 0x%x\n",
689 ap->id, ap->device->devno,
690 __FUNCTION__, status);
691 }
692
693 /* always return success */
694out:
695 return 0;
696}
697
698
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 785bf50488e9..90081e5ea80e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1737,6 +1737,14 @@ int ata_dev_configure(struct ata_device *dev)
1737 if (ap->ops->dev_config) 1737 if (ap->ops->dev_config)
1738 ap->ops->dev_config(ap, dev); 1738 ap->ops->dev_config(ap, dev);
1739 1739
1740 /* set _SDD */
1741 rc = ata_acpi_push_id(ap, dev->devno);
1742 if (rc) {
1743 ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
1744 rc);
1745 goto err_out_nosup;
1746 }
1747
1740 if (ata_msg_probe(ap)) 1748 if (ata_msg_probe(ap))
1741 ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", 1749 ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
1742 __FUNCTION__, ata_chk_status(ap)); 1750 __FUNCTION__, ata_chk_status(ap));
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index ea02903e8503..0ad7781d72a3 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -91,11 +91,16 @@ extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
91/* libata-acpi.c */ 91/* libata-acpi.c */
92#ifdef CONFIG_SATA_ACPI 92#ifdef CONFIG_SATA_ACPI
93extern int ata_acpi_exec_tfs(struct ata_port *ap); 93extern int ata_acpi_exec_tfs(struct ata_port *ap);
94extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix);
94#else 95#else
95static inline int ata_acpi_exec_tfs(struct ata_port *ap) 96static inline int ata_acpi_exec_tfs(struct ata_port *ap)
96{ 97{
97 return 0; 98 return 0;
98} 99}
100static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
101{
102 return 0;
103}
99#endif 104#endif
100 105
101/* libata-scsi.c */ 106/* libata-scsi.c */