Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 49056
b: refs/heads/master
c: 7ea1fbc
h: refs/heads/master
v: v3
  • Loading branch information
Kristen Carlson Accardi authored and Jeff Garzik committed Feb 16, 2007
1 parent 241e48a commit f8baa15
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 11ef697b37e3c85ce1ac21f7711babf1f5b12784
refs/heads/master: 7ea1fbc2a2449bc034a3d255f36f2e5486d52fe8
96 changes: 96 additions & 0 deletions trunk/drivers/ata/libata-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,3 +600,99 @@ 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: ap->id: %d, ix = %d, port#: %d\n",
__FUNCTION__, ap->id, 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,
"ata%u(%u): %s _SDD error: status = 0x%x\n",
ap->id, ap->device->devno,
__FUNCTION__, status);
}

/* always return success */
out:
return 0;
}


8 changes: 8 additions & 0 deletions trunk/drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,14 @@ int ata_dev_configure(struct ata_device *dev)
if (ap->ops->dev_config)
ap->ops->dev_config(ap, dev);

/* set _SDD */
rc = ata_acpi_push_id(ap, dev->devno);
if (rc) {
ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
rc);
goto err_out_nosup;
}

if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
__FUNCTION__, ata_chk_status(ap));
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/ata/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,16 @@ extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
/* libata-acpi.c */
#ifdef CONFIG_SATA_ACPI
extern int ata_acpi_exec_tfs(struct ata_port *ap);
extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix);
#else
static inline int ata_acpi_exec_tfs(struct ata_port *ap)
{
return 0;
}
static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
{
return 0;
}
#endif

/* libata-scsi.c */
Expand Down

0 comments on commit f8baa15

Please sign in to comment.