Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 311463
b: refs/heads/master
c: 6b66d95
h: refs/heads/master
i:
  311461: cdeb417
  311459: 50756e6
  311455: 4706afe
v: v3
  • Loading branch information
Matthew Garrett authored and Jeff Garzik committed Jun 29, 2012
1 parent 6a2cce6 commit c84651f
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: de50ada55b6b83b54b817911ec42dc590e1c1738
refs/heads/master: 6b66d95895c149cbc04d4fac5a2f5477c543a8ae
4 changes: 2 additions & 2 deletions trunk/drivers/acpi/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ int register_acpi_bus_type(struct acpi_bus_type *type)
}
return -ENODEV;
}
EXPORT_SYMBOL(register_acpi_bus_type);

int unregister_acpi_bus_type(struct acpi_bus_type *type)
{
Expand All @@ -54,6 +55,7 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type)
}
return -ENODEV;
}
EXPORT_SYMBOL(unregister_acpi_bus_type);

static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
{
Expand All @@ -69,7 +71,6 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
up_read(&bus_type_sem);
return ret;
}
EXPORT_SYMBOL_GPL(register_acpi_bus_type);

static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
{
Expand All @@ -86,7 +87,6 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
up_read(&bus_type_sem);
return ret;
}
EXPORT_SYMBOL_GPL(unregister_acpi_bus_type);

/* Get device's handler per its address under its parent */
struct acpi_find_child {
Expand Down
137 changes: 137 additions & 0 deletions trunk/drivers/ata/libata-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,39 @@ static void ata_acpi_clear_gtf(struct ata_device *dev)
dev->gtf_cache = NULL;
}

static acpi_handle ap_acpi_handle(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_ACPI_SATA)
return NULL;

/*
* If acpi bind operation has already happened, we can get the handle
* for the port by checking the corresponding scsi_host device's
* firmware node, otherwise we will need to find out the handle from
* its parent's acpi node.
*/
if (ap->scsi_host)
return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev);
else
return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev),
ap->port_no);
}

static acpi_handle dev_acpi_handle(struct ata_device *dev)
{
acpi_integer adr;
struct ata_port *ap = dev->link->ap;

if (ap->flags & ATA_FLAG_ACPI_SATA) {
if (!sata_pmp_attached(ap))
adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
else
adr = SATA_ADR(ap->port_no, dev->link->pmp);
return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), adr);
} else
return acpi_get_child(ap_acpi_handle(ap), dev->devno);
}

/**
* ata_acpi_associate_sata_port - associate SATA port with ACPI objects
* @ap: target SATA port
Expand Down Expand Up @@ -1018,3 +1051,107 @@ void ata_acpi_on_disable(struct ata_device *dev)
{
ata_acpi_clear_gtf(dev);
}

static int compat_pci_ata(struct ata_port *ap)
{
struct device *dev = ap->tdev.parent;
struct pci_dev *pdev;

if (!is_pci_dev(dev))
return 0;

pdev = to_pci_dev(dev);

if ((pdev->class >> 8) != PCI_CLASS_STORAGE_SATA &&
(pdev->class >> 8) != PCI_CLASS_STORAGE_IDE)
return 0;

return 1;
}

static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)
{
if (ap->flags & ATA_FLAG_ACPI_SATA)
return -ENODEV;

*handle = acpi_get_child(DEVICE_ACPI_HANDLE(ap->tdev.parent),
ap->port_no);

if (!*handle)
return -ENODEV;

return 0;
}

static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
acpi_handle *handle)
{
struct ata_device *ata_dev;

if (ap->flags & ATA_FLAG_ACPI_SATA)
ata_dev = &ap->link.device[sdev->channel];
else
ata_dev = &ap->link.device[sdev->id];

*handle = dev_acpi_handle(ata_dev);

if (!*handle)
return -ENODEV;

return 0;
}

static int is_ata_port(const struct device *dev)
{
return dev->type == &ata_port_type;
}

static struct ata_port *dev_to_ata_port(struct device *dev)
{
while (!is_ata_port(dev)) {
if (!dev->parent)
return NULL;
dev = dev->parent;
}
return to_ata_port(dev);
}

static int ata_acpi_find_device(struct device *dev, acpi_handle *handle)
{
struct ata_port *ap = dev_to_ata_port(dev);

if (!ap)
return -ENODEV;

if (!compat_pci_ata(ap))
return -ENODEV;

if (scsi_is_host_device(dev))
return ata_acpi_bind_host(ap, handle);
else if (scsi_is_sdev_device(dev)) {
struct scsi_device *sdev = to_scsi_device(dev);

return ata_acpi_bind_device(ap, sdev, handle);
} else
return -ENODEV;
}

static int ata_acpi_find_dummy(struct device *dev, acpi_handle *handle)
{
return -ENODEV;
}

static struct acpi_bus_type ata_acpi_bus = {
.find_bridge = ata_acpi_find_dummy,
.find_device = ata_acpi_find_device,
};

int ata_acpi_register(void)
{
return scsi_register_acpi_bus_type(&ata_acpi_bus);
}

void ata_acpi_unregister(void)
{
scsi_unregister_acpi_bus_type(&ata_acpi_bus);
}
5 changes: 3 additions & 2 deletions trunk/drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5288,8 +5288,6 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
return rc;
}

#define to_ata_port(d) container_of(d, struct ata_port, tdev)

static int ata_port_suspend_common(struct device *dev, pm_message_t mesg)
{
struct ata_port *ap = to_ata_port(dev);
Expand Down Expand Up @@ -6513,6 +6511,8 @@ static int __init ata_init(void)

ata_parse_force_param();

ata_acpi_register();

rc = ata_sff_init();
if (rc) {
kfree(ata_force_tbl);
Expand All @@ -6539,6 +6539,7 @@ static void __exit ata_exit(void)
ata_release_transport(ata_scsi_transport_template);
libata_transport_exit();
ata_sff_exit();
ata_acpi_unregister();
kfree(ata_force_tbl);
}

Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/ata/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ extern const char *sata_spd_string(unsigned int spd);
extern int ata_port_probe(struct ata_port *ap);
extern void __ata_port_probe(struct ata_port *ap);

#define to_ata_port(d) container_of(d, struct ata_port, tdev)

/* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI
extern unsigned int ata_acpi_gtf_filter;
Expand All @@ -119,6 +121,8 @@ extern void ata_acpi_on_resume(struct ata_port *ap);
extern int ata_acpi_on_devcfg(struct ata_device *dev);
extern void ata_acpi_on_disable(struct ata_device *dev);
extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state);
extern int ata_acpi_register(void);
extern void ata_acpi_unregister(void);
#else
static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { }
static inline void ata_acpi_associate(struct ata_host *host) { }
Expand All @@ -129,6 +133,8 @@ static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; }
static inline void ata_acpi_on_disable(struct ata_device *dev) { }
static inline void ata_acpi_set_state(struct ata_port *ap,
pm_message_t state) { }
static inline int ata_acpi_register(void) { return 0; }
static void ata_acpi_unregister(void) { }
#endif

/* libata-scsi.c */
Expand Down

0 comments on commit c84651f

Please sign in to comment.