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:
Linus Torvalds 2013-09-03 18:19:53 -07:00
commit 357397a141
24 changed files with 423 additions and 427 deletions

View File

@ -4,27 +4,17 @@ SATA nodes are defined to describe on-chip Serial ATA controllers.
Each SATA controller should have its own node.
Required properties:
- compatible : compatible list, contains "calxeda,hb-ahci" or "snps,spear-ahci"
- compatible : compatible list, contains "snps,spear-ahci"
- interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping>
Optional properties:
- calxeda,port-phys: phandle-combophy and lane assignment, which maps each
SATA port to a combophy and a lane within that
combophy
- calxeda,sgpio-gpio: phandle-gpio bank, bit offset, and default on or off,
which indicates that the driver supports SGPIO
indicator lights using the indicated GPIOs
- calxeda,led-order : a u32 array that map port numbers to offsets within the
SGPIO bitstream.
- dma-coherent : Present if dma operations are coherent
Example:
sata@ffe08000 {
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x1000>;
interrupts = <115>;
calxeda,port-phys = <&combophy5 0 &combophy0 0 &combophy0 1
&combophy0 2 &combophy0 3>;
compatible = "snps,spear-ahci";
reg = <0xffe08000 0x1000>;
interrupts = <115>;
};

View File

@ -0,0 +1,44 @@
* Calxeda AHCI SATA Controller
SATA nodes are defined to describe on-chip Serial ATA controllers.
The Calxeda SATA controller mostly conforms to the AHCI interface
with some special extensions to add functionality.
Each SATA controller should have its own node.
Required properties:
- compatible : compatible list, contains "calxeda,hb-ahci"
- interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping>
Optional properties:
- dma-coherent : Present if dma operations are coherent
- calxeda,port-phys : phandle-combophy and lane assignment, which maps each
SATA port to a combophy and a lane within that
combophy
- calxeda,sgpio-gpio: phandle-gpio bank, bit offset, and default on or off,
which indicates that the driver supports SGPIO
indicator lights using the indicated GPIOs
- calxeda,led-order : a u32 array that map port numbers to offsets within the
SGPIO bitstream.
- calxeda,tx-atten : a u32 array that contains TX attenuation override
codes, one per port. The upper 3 bytes are always
0 and thus ignored.
- calxeda,pre-clocks : a u32 that indicates the number of additional clock
cycles to transmit before sending an SGPIO pattern
- calxeda,post-clocks: a u32 that indicates the number of additional clock
cycles to transmit after sending an SGPIO pattern
Example:
sata@ffe08000 {
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x1000>;
interrupts = <115>;
dma-coherent;
calxeda,port-phys = <&combophy5 0 &combophy0 0 &combophy0 1
&combophy0 2 &combophy0 3>;
calxeda,sgpio-gpio =<&gpioh 5 1 &gpioh 6 1 &gpioh 7 1>;
calxeda,led-order = <4 0 1 2 3>;
calxeda,tx-atten = <0xff 22 0xff 0xff 23>;
calxeda,pre-clocks = <10>;
calxeda,post-clocks = <0>;
};

View File

@ -1295,6 +1295,14 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
if (!(hpriv->flags & AHCI_HFLAG_NO_FPDMA_AA))
pi.flags |= ATA_FLAG_FPDMA_AA;
/*
* All AHCI controllers should be forward-compatible
* with the new auxiliary field. This code should be
* conditionalized if any buggy AHCI controllers are
* encountered.
*/
pi.flags |= ATA_FLAG_FPDMA_AUX;
}
if (hpriv->cap & HOST_CAP_PMP)

View File

@ -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);
}

View File

@ -569,10 +569,10 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis)
fis[14] = 0;
fis[15] = tf->ctl;
fis[16] = 0;
fis[17] = 0;
fis[18] = 0;
fis[19] = 0;
fis[16] = tf->auxiliary & 0xff;
fis[17] = (tf->auxiliary >> 8) & 0xff;
fis[18] = (tf->auxiliary >> 16) & 0xff;
fis[19] = (tf->auxiliary >> 24) & 0xff;
}
/**
@ -2139,6 +2139,22 @@ static int ata_dev_config_ncq(struct ata_device *dev,
else
snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth,
ddepth, aa_desc);
if ((ap->flags & ATA_FLAG_FPDMA_AUX) &&
ata_id_has_ncq_send_and_recv(dev->id)) {
err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV,
0, ap->sector_buf, 1);
if (err_mask) {
ata_dev_dbg(dev,
"failed to get NCQ Send/Recv Log Emask 0x%x\n",
err_mask);
} else {
dev->flags |= ATA_DFLAG_NCQ_SEND_RECV;
memcpy(dev->ncq_send_recv_cmds, ap->sector_buf,
ATA_LOG_NCQ_SEND_RECV_SIZE);
}
}
return 0;
}
@ -6150,8 +6166,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
if (rc)
goto err_tadd;
ata_acpi_hotplug_init(host);
/* set cable, sata_spd_limit and report */
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
@ -6632,8 +6646,6 @@ static int __init ata_init(void)
ata_parse_force_param();
ata_acpi_register();
rc = ata_sff_init();
if (rc) {
kfree(ata_force_tbl);
@ -6660,7 +6672,6 @@ 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);
}

View File

@ -49,7 +49,6 @@
#include <linux/hdreg.h>
#include <linux/uaccess.h>
#include <linux/suspend.h>
#include <linux/pm_qos.h>
#include <asm/unaligned.h>
#include "libata.h"
@ -3100,12 +3099,25 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
buf = page_address(sg_page(scsi_sglist(scmd)));
size = ata_set_lba_range_entries(buf, 512, block, n_block);
tf->protocol = ATA_PROT_DMA;
tf->hob_feature = 0;
tf->feature = ATA_DSM_TRIM;
tf->hob_nsect = (size / 512) >> 8;
tf->nsect = size / 512;
tf->command = ATA_CMD_DSM;
if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) {
/* Newer devices support queued TRIM commands */
tf->protocol = ATA_PROT_NCQ;
tf->command = ATA_CMD_FPDMA_SEND;
tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
tf->nsect = qc->tag << 3;
tf->hob_feature = (size / 512) >> 8;
tf->feature = size / 512;
tf->auxiliary = 1;
} else {
tf->protocol = ATA_PROT_DMA;
tf->hob_feature = 0;
tf->feature = ATA_DSM_TRIM;
tf->hob_nsect = (size / 512) >> 8;
tf->nsect = size / 512;
tf->command = ATA_CMD_DSM;
}
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
ATA_TFLAG_WRITE;
@ -3667,9 +3679,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
if (!IS_ERR(sdev)) {
dev->sdev = sdev;
scsi_device_put(sdev);
if (zpodd_dev_enabled(dev))
dev_pm_qos_expose_flags(
&sdev->sdev_gendev, 0);
ata_scsi_acpi_bind(dev);
} else {
dev->sdev = NULL;
}
@ -3757,6 +3767,8 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
struct scsi_device *sdev;
unsigned long flags;
ata_scsi_acpi_unbind(dev);
/* Alas, we need to grab scan_mutex to ensure SCSI device
* state doesn't change underneath us and thus
* scsi_device_get() always succeeds. The mutex locking can
@ -3766,9 +3778,6 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
mutex_lock(&ap->scsi_host->scan_mutex);
spin_lock_irqsave(ap->lock, flags);
if (zpodd_dev_enabled(dev))
zpodd_exit(dev);
/* clearing dev->sdev is protected by host lock */
sdev = dev->sdev;
dev->sdev = NULL;
@ -3818,6 +3827,9 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
dev->flags &= ~ATA_DFLAG_DETACHED;
spin_unlock_irqrestore(ap->lock, flags);
if (zpodd_dev_enabled(dev))
zpodd_exit(dev);
ata_scsi_remove_dev(dev);
}
}

View File

@ -287,6 +287,7 @@ int ata_tport_add(struct device *parent,
dev->release = ata_tport_release;
dev_set_name(dev, "ata%d", ap->print_id);
transport_setup_device(dev);
ata_acpi_bind_port(ap);
error = device_add(dev);
if (error) {
goto tport_err;
@ -644,6 +645,7 @@ static int ata_tdev_add(struct ata_device *ata_dev)
dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
transport_setup_device(dev);
ata_acpi_bind_dev(ata_dev);
error = device_add(dev);
if (error) {
ata_tdev_free(ata_dev);

View File

@ -2,6 +2,7 @@
#include <linux/cdrom.h>
#include <linux/pm_runtime.h>
#include <linux/module.h>
#include <linux/pm_qos.h>
#include <scsi/scsi_device.h>
#include "libata.h"
@ -190,8 +191,8 @@ void zpodd_enable_run_wake(struct ata_device *dev)
sdev_disable_disk_events(dev->sdev);
zpodd->powered_off = true;
device_set_run_wake(&dev->sdev->sdev_gendev, true);
acpi_pm_device_run_wake(&dev->sdev->sdev_gendev, true);
device_set_run_wake(&dev->tdev, true);
acpi_pm_device_run_wake(&dev->tdev, true);
}
/* Disable runtime wake capability if it is enabled */
@ -200,8 +201,8 @@ void zpodd_disable_run_wake(struct ata_device *dev)
struct zpodd *zpodd = dev->zpodd;
if (zpodd->powered_off) {
acpi_pm_device_run_wake(&dev->sdev->sdev_gendev, false);
device_set_run_wake(&dev->sdev->sdev_gendev, false);
acpi_pm_device_run_wake(&dev->tdev, false);
device_set_run_wake(&dev->tdev, false);
}
}
@ -262,7 +263,7 @@ static void ata_acpi_add_pm_notifier(struct ata_device *dev)
static void ata_acpi_remove_pm_notifier(struct ata_device *dev)
{
acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->sdev->sdev_gendev);
acpi_handle handle = ata_dev_acpi_handle(dev);
acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, zpodd_wake_dev);
}
@ -290,6 +291,7 @@ void zpodd_init(struct ata_device *dev)
ata_acpi_add_pm_notifier(dev);
zpodd->dev = dev;
dev->zpodd = zpodd;
dev_pm_qos_expose_flags(&dev->tdev, 0);
}
void zpodd_exit(struct ata_device *dev)

View File

@ -118,11 +118,11 @@ 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);
extern void ata_acpi_bind(struct ata_device *dev);
extern void ata_acpi_unbind(struct ata_device *dev);
extern void ata_acpi_hotplug_init(struct ata_host *host);
extern void ata_acpi_bind_port(struct ata_port *ap);
extern void ata_acpi_bind_dev(struct ata_device *dev);
extern acpi_handle ata_dev_acpi_handle(struct ata_device *dev);
extern void ata_scsi_acpi_bind(struct ata_device *dev);
extern void ata_scsi_acpi_unbind(struct ata_device *dev);
#else
static inline void ata_acpi_dissociate(struct ata_host *host) { }
static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
@ -131,11 +131,10 @@ 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 inline void ata_acpi_unregister(void) { }
static inline void ata_acpi_bind(struct ata_device *dev) { }
static inline void ata_acpi_unbind(struct ata_device *dev) { }
static inline void ata_acpi_hotplug_init(struct ata_host *host) {}
static inline void ata_acpi_bind_port(struct ata_port *ap) {}
static inline void ata_acpi_bind_dev(struct ata_device *dev) {}
static inline void ata_scsi_acpi_bind(struct ata_device *dev) {}
static inline void ata_scsi_acpi_unbind(struct ata_device *dev) {}
#endif
/* libata-scsi.c */

View File

@ -39,7 +39,7 @@ static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
{
struct ata_port *ap = link->ap;
struct pata_acpi *acpi = ap->private_data;
if (ata_ap_acpi_handle(ap) == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
if (ACPI_HANDLE(&ap->tdev) == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
return -ENODEV;
return ata_sff_prereset(link, deadline);
@ -195,7 +195,7 @@ static int pacpi_port_start(struct ata_port *ap)
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
struct pata_acpi *acpi;
if (ata_ap_acpi_handle(ap) == NULL)
if (ACPI_HANDLE(&ap->tdev) == NULL)
return -ENODEV;
acpi = ap->private_data = devm_kzalloc(&pdev->dev, sizeof(struct pata_acpi), GFP_KERNEL);

View File

@ -654,7 +654,7 @@ static void arasan_cf_freeze(struct ata_port *ap)
ata_sff_freeze(ap);
}
void arasan_cf_error_handler(struct ata_port *ap)
static void arasan_cf_error_handler(struct ata_port *ap)
{
struct arasan_cf_dev *acdev = ap->host->private_data;
@ -683,7 +683,7 @@ static void arasan_cf_dma_start(struct arasan_cf_dev *acdev)
ata_sff_queue_work(&acdev->work);
}
unsigned int arasan_cf_qc_issue(struct ata_queued_cmd *qc)
static unsigned int arasan_cf_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct arasan_cf_dev *acdev = ap->host->private_data;

View File

@ -271,7 +271,7 @@ static int __init pata_at32_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct at32_ide_info *info;
struct ide_platform_data *board = pdev->dev.platform_data;
struct ide_platform_data *board = dev_get_platdata(&pdev->dev);
struct resource *res;
int irq;

View File

@ -315,7 +315,7 @@ static struct ata_port_operations pata_at91_port_ops = {
static int pata_at91_probe(struct platform_device *pdev)
{
struct at91_cf_data *board = pdev->dev.platform_data;
struct at91_cf_data *board = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct at91_ide_info *info;
struct resource *mem_res;

View File

@ -48,7 +48,7 @@ static unsigned int ixp4xx_mmio_data_xfer(struct ata_device *dev,
u16 *buf16 = (u16 *) buf;
struct ata_port *ap = dev->link->ap;
void __iomem *mmio = ap->ioaddr.data_addr;
struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
struct ixp4xx_pata_data *data = dev_get_platdata(ap->host->dev);
/* set the expansion bus in 16bit mode and restore
* 8 bit mode after the transaction.
@ -143,7 +143,7 @@ static int ixp4xx_pata_probe(struct platform_device *pdev)
struct resource *cs0, *cs1;
struct ata_host *host;
struct ata_port *ap;
struct ixp4xx_pata_data *data = pdev->dev.platform_data;
struct ixp4xx_pata_data *data = dev_get_platdata(&pdev->dev);
cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);

View File

@ -1037,7 +1037,7 @@ static void octeon_cf_shutdown(struct device *dev)
union cvmx_mio_boot_dma_cfgx dma_cfg;
union cvmx_mio_boot_dma_intx dma_int;
struct octeon_cf_port *cf_port = dev->platform_data;
struct octeon_cf_port *cf_port = dev_get_platdata(dev);
if (cf_port->dma_base) {
/* Stop and clear the dma engine. */

View File

@ -180,7 +180,7 @@ static int pata_platform_probe(struct platform_device *pdev)
struct resource *io_res;
struct resource *ctl_res;
struct resource *irq_res;
struct pata_platform_info *pp_info = pdev->dev.platform_data;
struct pata_platform_info *pp_info = dev_get_platdata(&pdev->dev);
/*
* Simple resource validation ..

View File

@ -238,7 +238,7 @@ static int pxa_ata_probe(struct platform_device *pdev)
struct resource *ctl_res;
struct resource *dma_res;
struct resource *irq_res;
struct pata_pxa_pdata *pdata = pdev->dev.platform_data;
struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev);
int ret = 0;
/*

View File

@ -241,8 +241,8 @@ static u8 pata_s3c_check_altstatus(struct ata_port *ap)
/*
* pata_s3c_data_xfer - Transfer data by PIO
*/
unsigned int pata_s3c_data_xfer(struct ata_device *dev, unsigned char *buf,
unsigned int buflen, int rw)
static unsigned int pata_s3c_data_xfer(struct ata_device *dev,
unsigned char *buf, unsigned int buflen, int rw)
{
struct ata_port *ap = dev->link->ap;
struct s3c_ide_info *info = ap->host->private_data;
@ -418,7 +418,7 @@ static struct ata_port_operations pata_s5p_port_ops = {
.set_piomode = pata_s3c_set_piomode,
};
static void pata_s3c_enable(void *s3c_ide_regbase, bool state)
static void pata_s3c_enable(void __iomem *s3c_ide_regbase, bool state)
{
u32 temp = readl(s3c_ide_regbase + S3C_ATA_CTRL);
temp = state ? (temp | 1) : (temp & ~1);
@ -475,7 +475,7 @@ static void pata_s3c_hwinit(struct s3c_ide_info *info,
static int __init pata_s3c_probe(struct platform_device *pdev)
{
struct s3c_ide_platdata *pdata = pdev->dev.platform_data;
struct s3c_ide_platdata *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct s3c_ide_info *info;
struct resource *res;
@ -617,7 +617,7 @@ static int pata_s3c_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct ata_host *host = platform_get_drvdata(pdev);
struct s3c_ide_platdata *pdata = pdev->dev.platform_data;
struct s3c_ide_platdata *pdata = dev_get_platdata(&pdev->dev);
struct s3c_ide_info *info = host->private_data;
pata_s3c_hwinit(info, pdata);

View File

@ -46,14 +46,19 @@
#define CR_BUSY 0x0001
#define CR_START 0x0001
#define CR_WR_RDN 0x0002
#define CPHY_TX_INPUT_STS 0x2001
#define CPHY_RX_INPUT_STS 0x2002
#define CPHY_SATA_OVERRIDE 0x4000
#define CPHY_OVERRIDE 0x2005
#define CPHY_SATA_TX_OVERRIDE 0x8000
#define CPHY_SATA_RX_OVERRIDE 0x4000
#define CPHY_TX_OVERRIDE 0x2004
#define CPHY_RX_OVERRIDE 0x2005
#define SPHY_LANE 0x100
#define SPHY_HALF_RATE 0x0001
#define CPHY_SATA_DPLL_MODE 0x0700
#define CPHY_SATA_DPLL_SHIFT 8
#define CPHY_SATA_DPLL_RESET (1 << 11)
#define CPHY_SATA_TX_ATTEN 0x1c00
#define CPHY_SATA_TX_ATTEN_SHIFT 10
#define CPHY_PHY_COUNT 6
#define CPHY_LANE_COUNT 4
#define CPHY_PORT_COUNT (CPHY_PHY_COUNT * CPHY_LANE_COUNT)
@ -66,6 +71,7 @@ struct phy_lane_info {
void __iomem *phy_base;
u8 lane_mapping;
u8 phy_devs;
u8 tx_atten;
};
static struct phy_lane_info port_data[CPHY_PORT_COUNT];
@ -76,9 +82,11 @@ static DEFINE_SPINLOCK(sgpio_lock);
#define SGPIO_PINS 3
#define SGPIO_PORTS 8
/* can be cast as an ahci_host_priv for compatibility with most functions */
struct ecx_plat_data {
u32 n_ports;
/* number of extra clocks that the SGPIO PIC controller expects */
u32 pre_clocks;
u32 post_clocks;
unsigned sgpio_gpio[SGPIO_PINS];
u32 sgpio_pattern;
u32 port_to_sgpio[SGPIO_PORTS];
@ -155,6 +163,9 @@ static ssize_t ecx_transmit_led_message(struct ata_port *ap, u32 state,
spin_lock_irqsave(&sgpio_lock, flags);
ecx_parse_sgpio(pdata, ap->port_no, state);
sgpio_out = pdata->sgpio_pattern;
for (i = 0; i < pdata->pre_clocks; i++)
ecx_led_cycle_clock(pdata);
gpio_set_value(pdata->sgpio_gpio[SLOAD], 1);
ecx_led_cycle_clock(pdata);
gpio_set_value(pdata->sgpio_gpio[SLOAD], 0);
@ -167,6 +178,8 @@ static ssize_t ecx_transmit_led_message(struct ata_port *ap, u32 state,
sgpio_out >>= 1;
ecx_led_cycle_clock(pdata);
}
for (i = 0; i < pdata->post_clocks; i++)
ecx_led_cycle_clock(pdata);
/* save off new led state for port/slot */
emp->led_state = state;
@ -201,6 +214,11 @@ static void highbank_set_em_messages(struct device *dev,
of_property_read_u32_array(np, "calxeda,led-order",
pdata->port_to_sgpio,
pdata->n_ports);
if (of_property_read_u32(np, "calxeda,pre-clocks", &pdata->pre_clocks))
pdata->pre_clocks = 0;
if (of_property_read_u32(np, "calxeda,post-clocks",
&pdata->post_clocks))
pdata->post_clocks = 0;
/* store em_loc */
hpriv->em_loc = 0;
@ -259,8 +277,27 @@ static void highbank_cphy_disable_overrides(u8 sata_port)
if (unlikely(port_data[sata_port].phy_base == NULL))
return;
tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
tmp &= ~CPHY_SATA_OVERRIDE;
combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
tmp &= ~CPHY_SATA_RX_OVERRIDE;
combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
}
static void cphy_override_tx_attenuation(u8 sata_port, u32 val)
{
u8 lane = port_data[sata_port].lane_mapping;
u32 tmp;
if (val & 0x8)
return;
tmp = combo_phy_read(sata_port, CPHY_TX_INPUT_STS + lane * SPHY_LANE);
tmp &= ~CPHY_SATA_TX_OVERRIDE;
combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp |= CPHY_SATA_TX_OVERRIDE;
combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp |= (val << CPHY_SATA_TX_ATTEN_SHIFT) & CPHY_SATA_TX_ATTEN;
combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
}
static void cphy_override_rx_mode(u8 sata_port, u32 val)
@ -268,21 +305,21 @@ static void cphy_override_rx_mode(u8 sata_port, u32 val)
u8 lane = port_data[sata_port].lane_mapping;
u32 tmp;
tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
tmp &= ~CPHY_SATA_OVERRIDE;
combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
tmp &= ~CPHY_SATA_RX_OVERRIDE;
combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp |= CPHY_SATA_OVERRIDE;
combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
tmp |= CPHY_SATA_RX_OVERRIDE;
combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp &= ~CPHY_SATA_DPLL_MODE;
tmp |= val << CPHY_SATA_DPLL_SHIFT;
combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp |= CPHY_SATA_DPLL_RESET;
combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp &= ~CPHY_SATA_DPLL_RESET;
combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
msleep(15);
}
@ -299,16 +336,20 @@ static void highbank_cphy_override_lane(u8 sata_port)
lane * SPHY_LANE);
} while ((tmp & SPHY_HALF_RATE) && (k++ < 1000));
cphy_override_rx_mode(sata_port, 3);
cphy_override_tx_attenuation(sata_port, port_data[sata_port].tx_atten);
}
static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
{
struct device_node *sata_node = dev->of_node;
int phy_count = 0, phy, port = 0;
int phy_count = 0, phy, port = 0, i;
void __iomem *cphy_base[CPHY_PHY_COUNT];
struct device_node *phy_nodes[CPHY_PHY_COUNT];
u32 tx_atten[CPHY_PORT_COUNT];
memset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT);
memset(phy_nodes, 0, sizeof(struct device_node*) * CPHY_PHY_COUNT);
memset(tx_atten, 0xff, CPHY_PORT_COUNT);
do {
u32 tmp;
@ -336,6 +377,10 @@ static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
of_node_put(phy_data.np);
port += 1;
} while (port < CPHY_PORT_COUNT);
of_property_read_u32_array(sata_node, "calxeda,tx-atten",
tx_atten, port);
for (i = 0; i < port; i++)
port_data[i].tx_atten = (u8) tx_atten[i];
return 0;
}
@ -479,6 +524,9 @@ static int ahci_highbank_probe(struct platform_device *pdev)
if (hpriv->cap & HOST_CAP_PMP)
pi.flags |= ATA_FLAG_PMP;
if (hpriv->cap & HOST_CAP_64)
dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
/* CAP.NP sometimes indicate the index of the last enabled
* port, at other times, that of the last possible port, so
* determining the maximum port number requires looking at

View File

@ -553,10 +553,15 @@ struct mv_host_priv {
u32 irq_mask_offset;
u32 unmask_all_irqs;
#if defined(CONFIG_HAVE_CLK)
/*
* Needed on some devices that require their clocks to be enabled.
* These are optional: if the platform device does not have any
* clocks, they won't be used. Also, if the underlying hardware
* does not support the common clock framework (CONFIG_HAVE_CLK=n),
* all the clock operations become no-ops (see clk.h).
*/
struct clk *clk;
struct clk **port_clks;
#endif
/*
* These consistent DMA memory pools give us guaranteed
* alignment for hardware-accessed data structures,
@ -4032,9 +4037,7 @@ static int mv_platform_probe(struct platform_device *pdev)
struct resource *res;
int n_ports = 0, irq = 0;
int rc;
#if defined(CONFIG_HAVE_CLK)
int port;
#endif
ata_print_version_once(&pdev->dev, DRV_VERSION);
@ -4058,7 +4061,7 @@ static int mv_platform_probe(struct platform_device *pdev)
of_property_read_u32(pdev->dev.of_node, "nr-ports", &n_ports);
irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
} else {
mv_platform_data = pdev->dev.platform_data;
mv_platform_data = dev_get_platdata(&pdev->dev);
n_ports = mv_platform_data->n_ports;
irq = platform_get_irq(pdev, 0);
}
@ -4068,13 +4071,11 @@ static int mv_platform_probe(struct platform_device *pdev)
if (!host || !hpriv)
return -ENOMEM;
#if defined(CONFIG_HAVE_CLK)
hpriv->port_clks = devm_kzalloc(&pdev->dev,
sizeof(struct clk *) * n_ports,
GFP_KERNEL);
if (!hpriv->port_clks)
return -ENOMEM;
#endif
host->private_data = hpriv;
hpriv->n_ports = n_ports;
hpriv->board_idx = chip_soc;
@ -4084,7 +4085,6 @@ static int mv_platform_probe(struct platform_device *pdev)
resource_size(res));
hpriv->base -= SATAHC0_REG_BASE;
#if defined(CONFIG_HAVE_CLK)
hpriv->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(hpriv->clk))
dev_notice(&pdev->dev, "cannot get optional clkdev\n");
@ -4098,7 +4098,6 @@ static int mv_platform_probe(struct platform_device *pdev)
if (!IS_ERR(hpriv->port_clks[port]))
clk_prepare_enable(hpriv->port_clks[port]);
}
#endif
/*
* (Re-)program MBUS remapping windows if we are asked to.
@ -4124,7 +4123,6 @@ static int mv_platform_probe(struct platform_device *pdev)
return 0;
err:
#if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) {
clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk);
@ -4135,7 +4133,6 @@ err:
clk_put(hpriv->port_clks[port]);
}
}
#endif
return rc;
}
@ -4151,13 +4148,10 @@ err:
static int mv_platform_remove(struct platform_device *pdev)
{
struct ata_host *host = platform_get_drvdata(pdev);
#if defined(CONFIG_HAVE_CLK)
struct mv_host_priv *hpriv = host->private_data;
int port;
#endif
ata_host_detach(host);
#if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) {
clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk);
@ -4168,7 +4162,6 @@ static int mv_platform_remove(struct platform_device *pdev)
clk_put(hpriv->port_clks[port]);
}
}
#endif
return 0;
}
@ -4428,9 +4421,6 @@ static int mv_pci_device_resume(struct pci_dev *pdev)
#endif
#endif
static int mv_platform_probe(struct platform_device *pdev);
static int mv_platform_remove(struct platform_device *pdev);
static int __init mv_init(void)
{
int rc = -ENODEV;

View File

@ -778,10 +778,6 @@ static int sata_rcar_probe(struct platform_device *pdev)
int irq;
int ret = 0;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (mem == NULL)
return -EINVAL;
irq = platform_get_irq(pdev, 0);
if (irq <= 0)
return -EINVAL;
@ -807,6 +803,7 @@ static int sata_rcar_probe(struct platform_device *pdev)
host->private_data = priv;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(priv->base)) {
ret = PTR_ERR(priv->base);

View File

@ -68,28 +68,6 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = {
struct kmem_cache *scsi_sdb_cache;
#ifdef CONFIG_ACPI
#include <acpi/acpi_bus.h>
static bool acpi_scsi_bus_match(struct device *dev)
{
return dev->bus == &scsi_bus_type;
}
int scsi_register_acpi_bus_type(struct acpi_bus_type *bus)
{
bus->match = acpi_scsi_bus_match;
return register_acpi_bus_type(bus);
}
EXPORT_SYMBOL_GPL(scsi_register_acpi_bus_type);
void scsi_unregister_acpi_bus_type(struct acpi_bus_type *bus)
{
unregister_acpi_bus_type(bus);
}
EXPORT_SYMBOL_GPL(scsi_unregister_acpi_bus_type);
#endif
/*
* When to reinvoke queueing after a resource shortage. It's 3 msecs to
* not change behaviour from the previous unplug mechanism, experimentation

View File

@ -239,6 +239,8 @@ enum {
ATA_CMD_WRITE_QUEUED_FUA_EXT = 0x3E,
ATA_CMD_FPDMA_READ = 0x60,
ATA_CMD_FPDMA_WRITE = 0x61,
ATA_CMD_FPDMA_SEND = 0x64,
ATA_CMD_FPDMA_RECV = 0x65,
ATA_CMD_PIO_READ = 0x20,
ATA_CMD_PIO_READ_EXT = 0x24,
ATA_CMD_PIO_WRITE = 0x30,
@ -293,8 +295,13 @@ enum {
/* marked obsolete in the ATA/ATAPI-7 spec */
ATA_CMD_RESTORE = 0x10,
/* Subcmds for ATA_CMD_FPDMA_SEND */
ATA_SUBCMD_FPDMA_SEND_DSM = 0x00,
ATA_SUBCMD_FPDMA_SEND_WR_LOG_DMA_EXT = 0x02,
/* READ_LOG_EXT pages */
ATA_LOG_SATA_NCQ = 0x10,
ATA_LOG_NCQ_SEND_RECV = 0x13,
ATA_LOG_SATA_ID_DEV_DATA = 0x30,
ATA_LOG_SATA_SETTINGS = 0x08,
ATA_LOG_DEVSLP_OFFSET = 0x30,
@ -305,6 +312,15 @@ enum {
ATA_LOG_DEVSLP_VALID = 0x07,
ATA_LOG_DEVSLP_VALID_MASK = 0x80,
/* NCQ send and receive log */
ATA_LOG_NCQ_SEND_RECV_SUBCMDS_OFFSET = 0x00,
ATA_LOG_NCQ_SEND_RECV_SUBCMDS_DSM = (1 << 0),
ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET = 0x04,
ATA_LOG_NCQ_SEND_RECV_DSM_TRIM = (1 << 0),
ATA_LOG_NCQ_SEND_RECV_RD_LOG_OFFSET = 0x08,
ATA_LOG_NCQ_SEND_RECV_WR_LOG_OFFSET = 0x0C,
ATA_LOG_NCQ_SEND_RECV_SIZE = 0x10,
/* READ/WRITE LONG (obsolete) */
ATA_CMD_READ_LONG = 0x22,
ATA_CMD_READ_LONG_ONCE = 0x23,
@ -446,22 +462,6 @@ enum {
SERR_TRANS_ST_ERROR = (1 << 24), /* Transport state trans. error */
SERR_UNRECOG_FIS = (1 << 25), /* Unrecognized FIS */
SERR_DEV_XCHG = (1 << 26), /* device exchanged */
/* struct ata_taskfile flags */
ATA_TFLAG_LBA48 = (1 << 0), /* enable 48-bit LBA and "HOB" */
ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */
ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */
ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */
ATA_TFLAG_LBA = (1 << 4), /* enable LBA */
ATA_TFLAG_FUA = (1 << 5), /* enable FUA */
ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */
/* protocol flags */
ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */
ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */
ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA,
ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */
ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */
};
enum ata_tf_protocols {
@ -488,83 +488,6 @@ struct ata_bmdma_prd {
__le32 flags_len;
};
struct ata_taskfile {
unsigned long flags; /* ATA_TFLAG_xxx */
u8 protocol; /* ATA_PROT_xxx */
u8 ctl; /* control reg */
u8 hob_feature; /* additional data */
u8 hob_nsect; /* to support LBA48 */
u8 hob_lbal;
u8 hob_lbam;
u8 hob_lbah;
u8 feature;
u8 nsect;
u8 lbal;
u8 lbam;
u8 lbah;
u8 device;
u8 command; /* IO operation */
};
/*
* protocol tests
*/
static inline unsigned int ata_prot_flags(u8 prot)
{
switch (prot) {
case ATA_PROT_NODATA:
return 0;
case ATA_PROT_PIO:
return ATA_PROT_FLAG_PIO;
case ATA_PROT_DMA:
return ATA_PROT_FLAG_DMA;
case ATA_PROT_NCQ:
return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ;
case ATAPI_PROT_NODATA:
return ATA_PROT_FLAG_ATAPI;
case ATAPI_PROT_PIO:
return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO;
case ATAPI_PROT_DMA:
return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA;
}
return 0;
}
static inline int ata_is_atapi(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI;
}
static inline int ata_is_nodata(u8 prot)
{
return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA);
}
static inline int ata_is_pio(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO;
}
static inline int ata_is_dma(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA;
}
static inline int ata_is_ncq(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ;
}
static inline int ata_is_data(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA;
}
/*
* id tests
*/
@ -865,6 +788,11 @@ static inline int ata_id_rotation_rate(const u16 *id)
return val;
}
static inline bool ata_id_has_ncq_send_and_recv(const u16 *id)
{
return id[ATA_ID_SATA_CAPABILITY_2] & BIT(6);
}
static inline bool ata_id_has_trim(const u16 *id)
{
if (ata_id_major_version(id) >= 7 &&
@ -1060,15 +988,6 @@ static inline unsigned ata_set_lba_range_entries(void *_buffer,
return used_bytes;
}
static inline int is_multi_taskfile(struct ata_taskfile *tf)
{
return (tf->command == ATA_CMD_READ_MULTI) ||
(tf->command == ATA_CMD_WRITE_MULTI) ||
(tf->command == ATA_CMD_READ_MULTI_EXT) ||
(tf->command == ATA_CMD_WRITE_MULTI_EXT) ||
(tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT);
}
static inline bool ata_ok(u8 status)
{
return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR))

View File

@ -138,6 +138,22 @@ enum {
ATA_SHT_THIS_ID = -1,
ATA_SHT_USE_CLUSTERING = 1,
/* struct ata_taskfile flags */
ATA_TFLAG_LBA48 = (1 << 0), /* enable 48-bit LBA and "HOB" */
ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */
ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */
ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */
ATA_TFLAG_LBA = (1 << 4), /* enable LBA */
ATA_TFLAG_FUA = (1 << 5), /* enable FUA */
ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */
/* protocol flags */
ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */
ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */
ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA,
ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */
ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */
/* struct ata_device stuff */
ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */
ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */
@ -156,6 +172,7 @@ enum {
ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */
ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */
ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */
ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
ATA_DFLAG_DETACH = (1 << 24),
@ -207,6 +224,7 @@ enum {
ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
ATA_FLAG_AN = (1 << 18), /* controller supports AN */
ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */
ATA_FLAG_FPDMA_AUX = (1 << 20), /* controller supports H2DFIS aux field */
ATA_FLAG_EM = (1 << 21), /* driver supports enclosure
* management */
ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity
@ -518,6 +536,33 @@ enum sw_activity {
BLINK_OFF,
};
struct ata_taskfile {
unsigned long flags; /* ATA_TFLAG_xxx */
u8 protocol; /* ATA_PROT_xxx */
u8 ctl; /* control reg */
u8 hob_feature; /* additional data */
u8 hob_nsect; /* to support LBA48 */
u8 hob_lbal;
u8 hob_lbam;
u8 hob_lbah;
u8 feature;
u8 nsect;
u8 lbal;
u8 lbam;
u8 lbah;
u8 device;
u8 command; /* IO operation */
u32 auxiliary; /* auxiliary field */
/* from SATA 3.1 and */
/* ATA-8 ACS-3 */
};
#ifdef CONFIG_ATA_SFF
struct ata_ioports {
void __iomem *cmd_addr;
@ -660,6 +705,9 @@ struct ata_device {
/* DEVSLP Timing Variables from Identify Device Data Log */
u8 devslp_timing[ATA_LOG_DEVSLP_SIZE];
/* NCQ send and receive log subcommand support */
u8 ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_SIZE];
/* error history */
int spdn_cnt;
/* ering is CLEAR_END, read comment above CLEAR_END */
@ -959,6 +1007,69 @@ extern const unsigned long sata_deb_timing_long[];
extern struct ata_port_operations ata_dummy_port_ops;
extern const struct ata_port_info ata_dummy_port_info;
/*
* protocol tests
*/
static inline unsigned int ata_prot_flags(u8 prot)
{
switch (prot) {
case ATA_PROT_NODATA:
return 0;
case ATA_PROT_PIO:
return ATA_PROT_FLAG_PIO;
case ATA_PROT_DMA:
return ATA_PROT_FLAG_DMA;
case ATA_PROT_NCQ:
return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ;
case ATAPI_PROT_NODATA:
return ATA_PROT_FLAG_ATAPI;
case ATAPI_PROT_PIO:
return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO;
case ATAPI_PROT_DMA:
return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA;
}
return 0;
}
static inline int ata_is_atapi(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI;
}
static inline int ata_is_nodata(u8 prot)
{
return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA);
}
static inline int ata_is_pio(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO;
}
static inline int ata_is_dma(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA;
}
static inline int ata_is_ncq(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ;
}
static inline int ata_is_data(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA;
}
static inline int is_multi_taskfile(struct ata_taskfile *tf)
{
return (tf->command == ATA_CMD_READ_MULTI) ||
(tf->command == ATA_CMD_WRITE_MULTI) ||
(tf->command == ATA_CMD_READ_MULTI_EXT) ||
(tf->command == ATA_CMD_WRITE_MULTI_EXT) ||
(tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT);
}
static inline const unsigned long *
sata_ehc_deb_timing(struct ata_eh_context *ehc)
{
@ -1142,8 +1253,6 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm);
int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm);
unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev,
const struct ata_acpi_gtm *gtm);
acpi_handle ata_ap_acpi_handle(struct ata_port *ap);
acpi_handle ata_dev_acpi_handle(struct ata_device *dev);
int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm);
#else
static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap)
@ -1497,6 +1606,13 @@ static inline int ata_ncq_enabled(struct ata_device *dev)
ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ;
}
static inline bool ata_fpdma_dsm_supported(struct ata_device *dev)
{
return (dev->flags & ATA_DFLAG_NCQ_SEND_RECV) &&
(dev->ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &
ATA_LOG_NCQ_SEND_RECV_DSM_TRIM);
}
static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
{
qc->tf.ctl |= ATA_NIEN;