Merge branch 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata changes from Tejun Heo: "Two interesting changes. - libata acpi handling has been restructured so that the association between ata devices and ACPI handles are less convoluted. This change shouldn't change visible behavior. - Queued TRIM support, which enables sending TRIM to the device without draining in-flight RW commands, is added. Currently only enabled for ahci (and likely to stay that way for the foreseeable future). Other changes are driver-specific updates / fixes" * 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: libata: bugfix: Remove __le32 in ata_tf_to_fis() libata: acpi: Remove ata_dev_acpi_handle stub in libata.h libata: Add support for queued DSM TRIM libata: Add support for SEND/RECEIVE FPDMA QUEUED libata: Add H2D FIS "auxiliary" port flag libata: Populate host-to-device FIS "auxiliary" field ata: acpi: rework the ata acpi bind support sata, highbank: send extra clock cycles in SGPIO patterns sata, highbank: set tx_atten override bits devicetree: create a separate binding description for sata_highbank drivers/ata/sata_rcar.c: simplify use of devm_ioremap_resource sata highbank: enable 64-bit DMA mask when using LPAE ata: pata_samsung_cf: add missing __iomem annotation ata: pata_arasan: Staticize local symbols sata_mv: Remove unneeded CONFIG_HAVE_CLK ifdefs ata: use dev_get_platdata() sata_mv: Remove unneeded forward declaration libata: acpi: remove dead code for ata_acpi_(un)bind libata: move 'struct ata_taskfile' and friends from ata.h to libata.h
This commit is contained in:
@@ -34,62 +34,25 @@ struct ata_acpi_gtf {
|
||||
u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Helper - belongs in the PCI layer somewhere eventually
|
||||
*/
|
||||
static int is_pci_dev(struct device *dev)
|
||||
{
|
||||
return (dev->bus == &pci_bus_type);
|
||||
}
|
||||
|
||||
static void ata_acpi_clear_gtf(struct ata_device *dev)
|
||||
{
|
||||
kfree(dev->gtf_cache);
|
||||
dev->gtf_cache = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_ap_acpi_handle - provide the acpi_handle for an ata_port
|
||||
* @ap: the acpi_handle returned will correspond to this port
|
||||
*
|
||||
* Returns the acpi_handle for the ACPI namespace object corresponding to
|
||||
* the ata_port passed into the function, or NULL if no such object exists
|
||||
*/
|
||||
acpi_handle ata_ap_acpi_handle(struct ata_port *ap)
|
||||
{
|
||||
if (ap->flags & ATA_FLAG_ACPI_SATA)
|
||||
return NULL;
|
||||
|
||||
return ap->scsi_host ?
|
||||
DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev) : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(ata_ap_acpi_handle);
|
||||
|
||||
/**
|
||||
* ata_dev_acpi_handle - provide the acpi_handle for an ata_device
|
||||
* @dev: the acpi_device returned will correspond to this port
|
||||
* @dev: the acpi_handle returned will correspond to this device
|
||||
*
|
||||
* Returns the acpi_handle for the ACPI namespace object corresponding to
|
||||
* the ata_device passed into the function, or NULL if no such object exists
|
||||
* or ACPI is disabled for this device due to consecutive errors.
|
||||
*/
|
||||
acpi_handle ata_dev_acpi_handle(struct ata_device *dev)
|
||||
{
|
||||
acpi_integer adr;
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
|
||||
if (libata_noacpi || dev->flags & ATA_DFLAG_ACPI_DISABLED)
|
||||
return NULL;
|
||||
|
||||
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(ata_ap_acpi_handle(ap), dev->devno);
|
||||
return dev->flags & ATA_DFLAG_ACPI_DISABLED ?
|
||||
NULL : ACPI_HANDLE(&dev->tdev);
|
||||
}
|
||||
EXPORT_SYMBOL(ata_dev_acpi_handle);
|
||||
|
||||
/* @ap and @dev are the same as ata_acpi_handle_hotplug() */
|
||||
static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
|
||||
@@ -156,10 +119,8 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
if (wait) {
|
||||
if (wait)
|
||||
ata_port_wait_eh(ap);
|
||||
flush_work(&ap->hotplug_task.work);
|
||||
}
|
||||
}
|
||||
|
||||
static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
|
||||
@@ -216,37 +177,55 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
|
||||
.uevent = ata_acpi_ap_uevent,
|
||||
};
|
||||
|
||||
void ata_acpi_hotplug_init(struct ata_host *host)
|
||||
/* bind acpi handle to pata port */
|
||||
void ata_acpi_bind_port(struct ata_port *ap)
|
||||
{
|
||||
int i;
|
||||
acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
acpi_handle handle;
|
||||
struct ata_device *dev;
|
||||
if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_handle)
|
||||
return;
|
||||
|
||||
if (!ap)
|
||||
continue;
|
||||
ACPI_HANDLE_SET(&ap->tdev, acpi_get_child(host_handle, ap->port_no));
|
||||
|
||||
handle = ata_ap_acpi_handle(ap);
|
||||
if (handle) {
|
||||
/* we might be on a docking station */
|
||||
register_hotplug_dock_device(handle,
|
||||
&ata_acpi_ap_dock_ops, ap,
|
||||
NULL, NULL);
|
||||
}
|
||||
if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
|
||||
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
|
||||
|
||||
ata_for_each_dev(dev, &ap->link, ALL) {
|
||||
handle = ata_dev_acpi_handle(dev);
|
||||
if (!handle)
|
||||
continue;
|
||||
/* we might be on a docking station */
|
||||
register_hotplug_dock_device(ACPI_HANDLE(&ap->tdev),
|
||||
&ata_acpi_ap_dock_ops, ap, NULL, NULL);
|
||||
}
|
||||
|
||||
/* we might be on a docking station */
|
||||
register_hotplug_dock_device(handle,
|
||||
&ata_acpi_dev_dock_ops,
|
||||
dev, NULL, NULL);
|
||||
}
|
||||
void ata_acpi_bind_dev(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
acpi_handle port_handle = ACPI_HANDLE(&ap->tdev);
|
||||
acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
|
||||
acpi_handle parent_handle;
|
||||
u64 adr;
|
||||
|
||||
/*
|
||||
* For both sata/pata devices, host handle is required.
|
||||
* For pata device, port handle is also required.
|
||||
*/
|
||||
if (libata_noacpi || !host_handle ||
|
||||
(!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_handle))
|
||||
return;
|
||||
|
||||
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);
|
||||
parent_handle = host_handle;
|
||||
} else {
|
||||
adr = dev->devno;
|
||||
parent_handle = port_handle;
|
||||
}
|
||||
|
||||
ACPI_HANDLE_SET(&dev->tdev, acpi_get_child(parent_handle, adr));
|
||||
|
||||
register_hotplug_dock_device(ata_dev_acpi_handle(dev),
|
||||
&ata_acpi_dev_dock_ops, dev, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,18 +249,34 @@ void ata_acpi_dissociate(struct ata_host *host)
|
||||
struct ata_port *ap = host->ports[i];
|
||||
const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
|
||||
|
||||
if (ata_ap_acpi_handle(ap) && gtm)
|
||||
if (ACPI_HANDLE(&ap->tdev) && gtm)
|
||||
ata_acpi_stm(ap, gtm);
|
||||
}
|
||||
}
|
||||
|
||||
static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle,
|
||||
struct ata_acpi_gtm *gtm)
|
||||
/**
|
||||
* ata_acpi_gtm - execute _GTM
|
||||
* @ap: target ATA port
|
||||
* @gtm: out parameter for _GTM result
|
||||
*
|
||||
* Evaluate _GTM and store the result in @gtm.
|
||||
*
|
||||
* LOCKING:
|
||||
* EH context.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
|
||||
*/
|
||||
int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
|
||||
{
|
||||
struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
|
||||
union acpi_object *out_obj;
|
||||
acpi_status status;
|
||||
int rc = 0;
|
||||
acpi_handle handle = ACPI_HANDLE(&ap->tdev);
|
||||
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
status = acpi_evaluate_object(handle, "_GTM", NULL, &output);
|
||||
|
||||
@@ -317,27 +312,6 @@ static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_acpi_gtm - execute _GTM
|
||||
* @ap: target ATA port
|
||||
* @gtm: out parameter for _GTM result
|
||||
*
|
||||
* Evaluate _GTM and store the result in @gtm.
|
||||
*
|
||||
* LOCKING:
|
||||
* EH context.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
|
||||
*/
|
||||
int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
|
||||
{
|
||||
if (ata_ap_acpi_handle(ap))
|
||||
return __ata_acpi_gtm(ap, ata_ap_acpi_handle(ap), gtm);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ata_acpi_gtm);
|
||||
|
||||
/**
|
||||
@@ -374,8 +348,8 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
|
||||
input.count = 3;
|
||||
input.pointer = in_params;
|
||||
|
||||
status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_STM", &input,
|
||||
NULL);
|
||||
status = acpi_evaluate_object(ACPI_HANDLE(&ap->tdev), "_STM",
|
||||
&input, NULL);
|
||||
|
||||
if (status == AE_NOT_FOUND)
|
||||
return -ENOENT;
|
||||
@@ -850,7 +824,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
|
||||
const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
|
||||
struct ata_device *dev;
|
||||
|
||||
if (ata_ap_acpi_handle(ap) && gtm) {
|
||||
if (ACPI_HANDLE(&ap->tdev) && gtm) {
|
||||
/* _GTM valid */
|
||||
|
||||
/* restore timing parameters */
|
||||
@@ -894,8 +868,7 @@ static int ata_acpi_choose_suspend_state(struct ata_device *dev, bool runtime)
|
||||
d_max_in = ACPI_STATE_D3_HOT;
|
||||
|
||||
out:
|
||||
return acpi_pm_device_sleep_state(&dev->sdev->sdev_gendev,
|
||||
NULL, d_max_in);
|
||||
return acpi_pm_device_sleep_state(&dev->tdev, NULL, d_max_in);
|
||||
}
|
||||
|
||||
static void sata_acpi_set_state(struct ata_port *ap, pm_message_t state)
|
||||
@@ -932,7 +905,7 @@ static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state)
|
||||
struct ata_device *dev;
|
||||
acpi_handle port_handle;
|
||||
|
||||
port_handle = ata_ap_acpi_handle(ap);
|
||||
port_handle = ACPI_HANDLE(&ap->tdev);
|
||||
if (!port_handle)
|
||||
return;
|
||||
|
||||
@@ -1063,109 +1036,16 @@ void ata_acpi_on_disable(struct ata_device *dev)
|
||||
ata_acpi_clear_gtf(dev);
|
||||
}
|
||||
|
||||
static int compat_pci_ata(struct ata_port *ap)
|
||||
void ata_scsi_acpi_bind(struct ata_device *dev)
|
||||
{
|
||||
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;
|
||||
acpi_handle handle = ata_dev_acpi_handle(dev);
|
||||
if (handle)
|
||||
acpi_dev_pm_add_dependent(handle, &dev->sdev->sdev_gendev);
|
||||
}
|
||||
|
||||
static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)
|
||||
void ata_scsi_acpi_unbind(struct ata_device *dev)
|
||||
{
|
||||
if (libata_noacpi || 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;
|
||||
|
||||
if (__ata_acpi_gtm(ap, *handle, &ap->__acpi_init_gtm) == 0)
|
||||
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
|
||||
|
||||
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) {
|
||||
if (!sata_pmp_attached(ap))
|
||||
ata_dev = &ap->link.device[sdev->id];
|
||||
else
|
||||
ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id];
|
||||
}
|
||||
else {
|
||||
ata_dev = &ap->link.device[sdev->id];
|
||||
}
|
||||
|
||||
*handle = ata_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 struct acpi_bus_type ata_acpi_bus = {
|
||||
.name = "ATA",
|
||||
.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);
|
||||
acpi_handle handle = ata_dev_acpi_handle(dev);
|
||||
if (handle)
|
||||
acpi_dev_pm_remove_dependent(handle, &dev->sdev->sdev_gendev);
|
||||
}
|
||||
|
Reference in New Issue
Block a user