Commit ededa4d3 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  libata: fix ATAPI draining
  libata: update atapi_eh_request_sense() such that lbam/lbah contains buffer size
  libata-acpi: implement _GTF command filtering
  libata-acpi: improve _GTF execution error handling and reporting
  libata-acpi: improve ACPI disabling
  libata-acpi: implement dev->gtf_cache and evaluate _GTF right after _STM during resume
  libata-acpi: implement and use ata_acpi_init_gtm()
  libata-acpi: add new hooks ata_acpi_dissociate() and ata_acpi_on_disable()
  libata: ata_dev_disable() should be called from EH context
  libata: add more opcodes to ata.h
  libata: update ata_*_printk() macros such that level can be a variable
  libata-acpi: adjust constness in ata_acpi_gtm/stm() parameters
  sata_mv: improve warnings about Highpoint RocketRAID 23xx cards
  libata: add ST3160023AS / 3.42 to NCQ blacklist
  libata: clear link->eh_info.serror from ata_std_postreset()
  sata_sil: fix spurious IRQ handling
parents 64396acc 140b5e59
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Copyright (C) 2006 Randy Dunlap * Copyright (C) 2006 Randy Dunlap
*/ */
#include <linux/module.h>
#include <linux/ata.h> #include <linux/ata.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -25,6 +26,18 @@ ...@@ -25,6 +26,18 @@
#include <acpi/acmacros.h> #include <acpi/acmacros.h>
#include <acpi/actypes.h> #include <acpi/actypes.h>
enum {
ATA_ACPI_FILTER_SETXFER = 1 << 0,
ATA_ACPI_FILTER_LOCK = 1 << 1,
ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER |
ATA_ACPI_FILTER_LOCK,
};
static unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644);
MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock)");
#define NO_PORT_MULT 0xffff #define NO_PORT_MULT 0xffff
#define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) #define SATA_ADR(root, pmp) (((root) << 16) | (pmp))
...@@ -41,6 +54,12 @@ static int is_pci_dev(struct device *dev) ...@@ -41,6 +54,12 @@ static int is_pci_dev(struct device *dev)
return (dev->bus == &pci_bus_type); 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_acpi_associate_sata_port - associate SATA port with ACPI objects * ata_acpi_associate_sata_port - associate SATA port with ACPI objects
* @ap: target SATA port * @ap: target SATA port
...@@ -94,6 +113,9 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) ...@@ -94,6 +113,9 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
dev->acpi_handle = acpi_get_child(ap->acpi_handle, i); dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
} }
if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
} }
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj,
...@@ -187,6 +209,32 @@ void ata_acpi_associate(struct ata_host *host) ...@@ -187,6 +209,32 @@ void ata_acpi_associate(struct ata_host *host)
} }
} }
/**
* ata_acpi_dissociate - dissociate ATA host from ACPI objects
* @host: target ATA host
*
* This function is called during driver detach after the whole host
* is shut down.
*
* LOCKING:
* EH context.
*/
void ata_acpi_dissociate(struct ata_host *host)
{
int i;
/* Restore initial _GTM values so that driver which attaches
* afterward can use them too.
*/
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
if (ap->acpi_handle && gtm)
ata_acpi_stm(ap, gtm);
}
}
/** /**
* ata_acpi_gtm - execute _GTM * ata_acpi_gtm - execute _GTM
* @ap: target ATA port * @ap: target ATA port
...@@ -200,7 +248,7 @@ void ata_acpi_associate(struct ata_host *host) ...@@ -200,7 +248,7 @@ void ata_acpi_associate(struct ata_host *host)
* RETURNS: * RETURNS:
* 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure. * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
*/ */
int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm) int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
{ {
struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER }; struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
union acpi_object *out_obj; union acpi_object *out_obj;
...@@ -259,15 +307,16 @@ EXPORT_SYMBOL_GPL(ata_acpi_gtm); ...@@ -259,15 +307,16 @@ EXPORT_SYMBOL_GPL(ata_acpi_gtm);
* RETURNS: * RETURNS:
* 0 on success, -ENOENT if _STM doesn't exist, -errno on failure. * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure.
*/ */
int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm) int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
{ {
acpi_status status; acpi_status status;
struct ata_acpi_gtm stm_buf = *stm;
struct acpi_object_list input; struct acpi_object_list input;
union acpi_object in_params[3]; union acpi_object in_params[3];
in_params[0].type = ACPI_TYPE_BUFFER; in_params[0].type = ACPI_TYPE_BUFFER;
in_params[0].buffer.length = sizeof(struct ata_acpi_gtm); in_params[0].buffer.length = sizeof(struct ata_acpi_gtm);
in_params[0].buffer.pointer = (u8 *)stm; in_params[0].buffer.pointer = (u8 *)&stm_buf;
/* Buffers for id may need byteswapping ? */ /* Buffers for id may need byteswapping ? */
in_params[1].type = ACPI_TYPE_BUFFER; in_params[1].type = ACPI_TYPE_BUFFER;
in_params[1].buffer.length = 512; in_params[1].buffer.length = 512;
...@@ -297,7 +346,6 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm); ...@@ -297,7 +346,6 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
* ata_dev_get_GTF - get the drive bootup default taskfile settings * ata_dev_get_GTF - get the drive bootup default taskfile settings
* @dev: target ATA device * @dev: target ATA device
* @gtf: output parameter for buffer containing _GTF taskfile arrays * @gtf: output parameter for buffer containing _GTF taskfile arrays
* @ptr_to_free: pointer which should be freed
* *
* This applies to both PATA and SATA drives. * This applies to both PATA and SATA drives.
* *
...@@ -311,11 +359,10 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm); ...@@ -311,11 +359,10 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
* EH context. * EH context.
* *
* RETURNS: * RETURNS:
* Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't * Number of taskfiles on success, 0 if _GTF doesn't exist. -EINVAL
* contain valid data. * if _GTF is invalid.
*/ */
static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf)
void **ptr_to_free)
{ {
struct ata_port *ap = dev->link->ap; struct ata_port *ap = dev->link->ap;
acpi_status status; acpi_status status;
...@@ -323,6 +370,12 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, ...@@ -323,6 +370,12 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
union acpi_object *out_obj; union acpi_object *out_obj;
int rc = 0; int rc = 0;
/* if _GTF is cached, use the cached value */
if (dev->gtf_cache) {
out_obj = dev->gtf_cache;
goto done;
}
/* set up output buffer */ /* set up output buffer */
output.length = ACPI_ALLOCATE_BUFFER; output.length = ACPI_ALLOCATE_BUFFER;
output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
...@@ -333,12 +386,14 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, ...@@ -333,12 +386,14 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
/* _GTF has no input parameters */ /* _GTF has no input parameters */
status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
out_obj = dev->gtf_cache = output.pointer;
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND) { if (status != AE_NOT_FOUND) {
ata_dev_printk(dev, KERN_WARNING, ata_dev_printk(dev, KERN_WARNING,
"_GTF evaluation failed (AE 0x%x)\n", "_GTF evaluation failed (AE 0x%x)\n",
status); status);
rc = -EINVAL;
} }
goto out_free; goto out_free;
} }
...@@ -350,14 +405,15 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, ...@@ -350,14 +405,15 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
__FUNCTION__, __FUNCTION__,
(unsigned long long)output.length, (unsigned long long)output.length,
output.pointer); output.pointer);
rc = -EINVAL;
goto out_free; goto out_free;
} }
out_obj = output.pointer;
if (out_obj->type != ACPI_TYPE_BUFFER) { if (out_obj->type != ACPI_TYPE_BUFFER) {
ata_dev_printk(dev, KERN_WARNING, ata_dev_printk(dev, KERN_WARNING,
"_GTF unexpected object type 0x%x\n", "_GTF unexpected object type 0x%x\n",
out_obj->type); out_obj->type);
rc = -EINVAL;
goto out_free; goto out_free;
} }
...@@ -365,21 +421,23 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, ...@@ -365,21 +421,23 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
ata_dev_printk(dev, KERN_WARNING, ata_dev_printk(dev, KERN_WARNING,
"unexpected _GTF length (%d)\n", "unexpected _GTF length (%d)\n",
out_obj->buffer.length); out_obj->buffer.length);
rc = -EINVAL;
goto out_free; goto out_free;
} }
*ptr_to_free = out_obj; done:
*gtf = (void *)out_obj->buffer.pointer;
rc = out_obj->buffer.length / REGS_PER_GTF; rc = out_obj->buffer.length / REGS_PER_GTF;
if (gtf) {
*gtf = (void *)out_obj->buffer.pointer;
if (ata_msg_probe(ap)) if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: returning " ata_dev_printk(dev, KERN_DEBUG,
"gtf=%p, gtf_count=%d, ptr_to_free=%p\n", "%s: returning gtf=%p, gtf_count=%d\n",
__FUNCTION__, *gtf, rc, *ptr_to_free); __FUNCTION__, *gtf, rc);
}
return rc; return rc;
out_free: out_free:
kfree(output.pointer); ata_acpi_clear_gtf(dev);
return rc; return rc;
} }
...@@ -393,22 +451,21 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, ...@@ -393,22 +451,21 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
int ata_acpi_cbl_80wire(struct ata_port *ap) int ata_acpi_cbl_80wire(struct ata_port *ap)
{ {
struct ata_acpi_gtm gtm; const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
int valid = 0; int valid = 0;
/* No _GTM data, no information */ if (!gtm)
if (ata_acpi_gtm(ap, &gtm) < 0)
return 0; return 0;
/* Split timing, DMA enabled */ /* Split timing, DMA enabled */
if ((gtm.flags & 0x11) == 0x11 && gtm.drive[0].dma < 55) if ((gtm->flags & 0x11) == 0x11 && gtm->drive[0].dma < 55)
valid |= 1; valid |= 1;
if ((gtm.flags & 0x14) == 0x14 && gtm.drive[1].dma < 55) if ((gtm->flags & 0x14) == 0x14 && gtm->drive[1].dma < 55)
valid |= 2; valid |= 2;
/* Shared timing, DMA enabled */ /* Shared timing, DMA enabled */
if ((gtm.flags & 0x11) == 0x01 && gtm.drive[0].dma < 55) if ((gtm->flags & 0x11) == 0x01 && gtm->drive[0].dma < 55)
valid |= 1; valid |= 1;
if ((gtm.flags & 0x14) == 0x04 && gtm.drive[0].dma < 55) if ((gtm->flags & 0x14) == 0x04 && gtm->drive[0].dma < 55)
valid |= 2; valid |= 2;
/* Drive check */ /* Drive check */
...@@ -421,8 +478,62 @@ int ata_acpi_cbl_80wire(struct ata_port *ap) ...@@ -421,8 +478,62 @@ int ata_acpi_cbl_80wire(struct ata_port *ap)
EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
static void ata_acpi_gtf_to_tf(struct ata_device *dev,
const struct ata_acpi_gtf *gtf,
struct ata_taskfile *tf)
{
ata_tf_init(dev, tf);
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
tf->feature = gtf->tf[0]; /* 0x1f1 */
tf->nsect = gtf->tf[1]; /* 0x1f2 */
tf->lbal = gtf->tf[2]; /* 0x1f3 */
tf->lbam = gtf->tf[3]; /* 0x1f4 */
tf->lbah = gtf->tf[4]; /* 0x1f5 */
tf->device = gtf->tf[5]; /* 0x1f6 */
tf->command = gtf->tf[6]; /* 0x1f7 */
}
static int ata_acpi_filter_tf(const struct ata_taskfile *tf,
const struct ata_taskfile *ptf)
{
if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_SETXFER) {
/* libata doesn't use ACPI to configure transfer mode.
* It will only confuse device configuration. Skip.
*/
if (tf->command == ATA_CMD_SET_FEATURES &&
tf->feature == SETFEATURES_XFER)
return 1;
}
if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_LOCK) {
/* BIOS writers, sorry but we don't wanna lock
* features unless the user explicitly said so.
*/
/* DEVICE CONFIGURATION FREEZE LOCK */
if (tf->command == ATA_CMD_CONF_OVERLAY &&
tf->feature == ATA_DCO_FREEZE_LOCK)
return 1;
/* SECURITY FREEZE LOCK */
if (tf->command == ATA_CMD_SEC_FREEZE_LOCK)
return 1;
/* SET MAX LOCK and SET MAX FREEZE LOCK */
if ((!ptf || ptf->command != ATA_CMD_READ_NATIVE_MAX) &&
tf->command == ATA_CMD_SET_MAX &&
(tf->feature == ATA_SET_MAX_LOCK ||
tf->feature == ATA_SET_MAX_FREEZE_LOCK))
return 1;
}
return 0;
}
/** /**
* taskfile_load_raw - send taskfile registers to host controller * ata_acpi_run_tf - send taskfile registers to host controller
* @dev: target ATA device * @dev: target ATA device
* @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
* *
...@@ -441,56 +552,77 @@ EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); ...@@ -441,56 +552,77 @@ EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
* EH context. * EH context.
* *
* RETURNS: * RETURNS:
* 0 on success, -errno on failure. * 1 if command is executed successfully. 0 if ignored, rejected or
* filtered out, -errno on other errors.
*/ */
static int taskfile_load_raw(struct ata_device *dev, static int ata_acpi_run_tf(struct ata_device *dev,
const struct ata_acpi_gtf *gtf) const struct ata_acpi_gtf *gtf,
const struct ata_acpi_gtf *prev_gtf)
{ {
struct ata_port *ap = dev->link->ap; struct ata_taskfile *pptf = NULL;
struct ata_taskfile tf, rtf; struct ata_taskfile tf, ptf, rtf;
unsigned int err_mask; unsigned int err_mask;
const char *level;
char msg[60];
int rc;
if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0) if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0)
&& (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0) && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
&& (gtf->tf[6] == 0)) && (gtf->tf[6] == 0))
return 0; return 0;
ata_tf_init(dev, &tf); ata_acpi_gtf_to_tf(dev, gtf, &tf);
if (prev_gtf) {
ata_acpi_gtf_to_tf(dev, prev_gtf, &ptf);
pptf = &ptf;
}
/* convert gtf to tf */ if (!ata_acpi_filter_tf(&tf, pptf)) {
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */ rtf = tf;
tf.protocol = ATA_PROT_NODATA; err_mask = ata_exec_internal(dev, &rtf, NULL,
tf.feature = gtf->tf[0]; /* 0x1f1 */ DMA_NONE, NULL, 0, 0);
tf.nsect = gtf->tf[1]; /* 0x1f2 */
tf.lbal = gtf->tf[2]; /* 0x1f3 */
tf.lbam = gtf->tf[3]; /* 0x1f4 */
tf.lbah = gtf->tf[4]; /* 0x1f5 */
tf.device = gtf->tf[5]; /* 0x1f6 */
tf.command = gtf->tf[6]; /* 0x1f7 */
if (ata_msg_probe(ap)) switch (err_mask) {
ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd " case 0:
"%02x/%02x:%02x:%02x:%02x:%02x:%02x\n", level = KERN_DEBUG;
tf.command, tf.feature, tf.nsect, snprintf(msg, sizeof(msg), "succeeded");
tf.lbal, tf.lbam, tf.lbah, tf.device); rc = 1;
break;
rtf = tf; case AC_ERR_DEV:
err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0, 0); level = KERN_INFO;
if (err_mask) { snprintf(msg, sizeof(msg),
ata_dev_printk(dev, KERN_ERR, "rejected by device (Stat=0x%02x Err=0x%02x)",
"ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed " rtf.command, rtf.feature);
"(Emask=0x%x Stat=0x%02x Err=0x%02x)\n", rc = 0;
tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam, break;
tf.lbah, tf.device, err_mask, rtf.command, rtf.feature);
return -EIO; default:
level = KERN_ERR;
snprintf(msg, sizeof(msg),
"failed (Emask=0x%x Stat=0x%02x Err=0x%02x)",
err_mask, rtf.command, rtf.feature);
rc = -EIO;
break;
}
} else {
level = KERN_INFO;
snprintf(msg, sizeof(msg), "filtered out");
rc = 0;
} }
return 0; ata_dev_printk(dev, level,
"ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x %s\n",
tf.command, tf.feature, tf.nsect, tf.lbal,
tf.lbam, tf.lbah, tf.device, msg);
return rc;
} }
/** /**
* ata_acpi_exec_tfs - get then write drive taskfile settings * ata_acpi_exec_tfs - get then write drive taskfile settings
* @dev: target ATA device * @dev: target ATA device
* @nr_executed: out paramter for the number of executed commands
* *
* Evaluate _GTF and excute returned taskfiles. * Evaluate _GTF and excute returned taskfiles.
* *
...@@ -498,35 +630,36 @@ static int taskfile_load_raw(struct ata_device *dev, ...@@ -498,35 +630,36 @@ static int taskfile_load_raw(struct ata_device *dev,
* EH context. * EH context.
* *
* RETURNS: * RETURNS:
* Number of executed taskfiles on success, 0 if _GTF doesn't exist or * Number of executed taskfiles on success, 0 if _GTF doesn't exist.
* doesn't contain valid data. -errno on other errors. * -errno on other errors.
*/ */
static int ata_acpi_exec_tfs(struct ata_device *dev) static int ata_acpi_exec_tfs(struct ata_device *dev, int *nr_executed)
{ {
struct ata_acpi_gtf *gtf = NULL; struct ata_acpi_gtf *gtf = NULL, *pgtf = NULL;
void *ptr_to_free = NULL;
int gtf_count, i, rc; int gtf_count, i, rc;
/* get taskfiles */ /* get taskfiles */
gtf_count = ata_dev_get_GTF(dev, &gtf, &ptr_to_free); rc = ata_dev_get_GTF(dev, &gtf);
if (rc < 0)
return rc;
gtf_count = rc;
/* execute them */ /* execute them */
for (i = 0, rc = 0; i < gtf_count; i++) { for (i = 0; i < gtf_count; i++, gtf++) {
int tmp; rc = ata_acpi_run_tf(dev, gtf, pgtf);
if (rc < 0)
/* ACPI errors are eventually ignored. Run till the break;
* end even after errors. if (rc) {
*/ (*nr_executed)++;
tmp = taskfile_load_raw(dev, gtf++); pgtf = gtf;
if (!rc) }
rc = tmp;
} }
kfree(ptr_to_free); ata_acpi_clear_gtf(dev);
if (rc == 0) if (rc < 0)
return gtf_count;
return rc; return rc;
return 0;
} }
/** /**
...@@ -596,27 +729,8 @@ static int ata_acpi_push_id(struct ata_device *dev) ...@@ -596,27 +729,8 @@ static int ata_acpi_push_id(struct ata_device *dev)
*/ */
int ata_acpi_on_suspend(struct ata_port *ap) int ata_acpi_on_suspend(struct ata_port *ap)
{ {
unsigned long flags; /* nada */
int rc;
/* proceed iff per-port acpi_handle is valid */
if (!ap->acpi_handle)
return 0; return 0;
BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
/* store timing parameters */
rc = ata_acpi_gtm(ap, &ap->acpi_gtm);
spin_lock_irqsave(ap->lock, flags);
if (rc == 0)
ap->pflags |= ATA_PFLAG_GTM_VALID;
else
ap->pflags &= ~ATA_PFLAG_GTM_VALID;
spin_unlock_irqrestore(ap->lock, flags);
if (rc == -ENOENT)
rc = 0;
return rc;
} }
/** /**
...@@ -631,18 +745,34 @@ int ata_acpi_on_suspend(struct ata_port *ap) ...@@ -631,18 +745,34 @@ int ata_acpi_on_suspend(struct ata_port *ap)
*/ */
void ata_acpi_on_resume(struct ata_port *ap) void ata_acpi_on_resume(struct ata_port *ap)
{ {
const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
struct ata_device *dev; struct ata_device *dev;
if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) { if (ap->acpi_handle && gtm) {
BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); /* _GTM valid */
/* restore timing parameters */ /* restore timing parameters */
ata_acpi_stm(ap, &ap->acpi_gtm); ata_acpi_stm(ap, gtm);
}
/* schedule _GTF */ /* _GTF should immediately follow _STM so that it can
ata_link_for_each_dev(dev, &ap->link) * use values set by _STM. Cache _GTF result and
* schedule _GTF.
*/
ata_link_for_each_dev(dev, &ap->link) {
ata_acpi_clear_gtf(dev);
if (ata_dev_get_GTF(dev, NULL) >= 0)
dev->flags |= ATA_DFLAG_ACPI_PENDING; dev->flags |= ATA_DFLAG_ACPI_PENDING;
}
} else {
/* SATA _GTF needs to be evaulated after _SDD and
* there's no reason to evaluate IDE _GTF early
* without _STM. Clear cache and schedule _GTF.
*/
ata_link_for_each_dev(dev, &ap->link) {
ata_acpi_clear_gtf(dev);
dev->flags |= ATA_DFLAG_ACPI_PENDING;
}
}
} }
/** /**
...@@ -664,6 +794,7 @@ int ata_acpi_on_devcfg(struct ata_device *dev) ...@@ -664,6 +794,7 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
struct ata_port *ap = dev->link->ap; struct ata_port *ap = dev->link->ap;
struct ata_eh_context *ehc = &ap->link.eh_context; struct ata_eh_context *ehc = &ap->link.eh_context;
int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
int nr_executed = 0;
int rc; int rc;
if (!dev->acpi_handle) if (!dev->acpi_handle)
...@@ -682,14 +813,14 @@ int ata_acpi_on_devcfg(struct ata_device *dev) ...@@ -682,14 +813,14 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
} }
/* do _GTF */ /* do _GTF */
rc = ata_acpi_exec_tfs(dev); rc = ata_acpi_exec_tfs(dev, &nr_executed);
if (rc < 0) if (rc)
goto acpi_err; goto acpi_err;
dev->flags &= ~ATA_DFLAG_ACPI_PENDING; dev->flags &= ~ATA_DFLAG_ACPI_PENDING;
/* refresh IDENTIFY page if any _GTF command has been executed */ /* refresh IDENTIFY page if any _GTF command has been executed */
if (rc > 0) { if (nr_executed) {
rc = ata_dev_reread_id(dev, 0); rc = ata_dev_reread_id(dev, 0);
if (rc < 0) { if (rc < 0) {
ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY " ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY "
...@@ -701,17 +832,39 @@ int ata_acpi_on_devcfg(struct ata_device *dev) ...@@ -701,17 +832,39 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
return 0; return 0;
acpi_err: acpi_err:
/* let EH retry on the first failure, disable ACPI on the second */ /* ignore evaluation failure if we can continue safely */
if (dev->flags & ATA_DFLAG_ACPI_FAILED) { if (rc == -EINVAL && !nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN))
ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the " return 0;
"second time, disabling (errno=%d)\n", rc);
/* fail and let EH retry once more for unknown IO errors */
if (!(dev->flags & ATA_DFLAG_ACPI_FAILED)) {
dev->flags |= ATA_DFLAG_ACPI_FAILED;
return rc;
}
ata_dev_printk(dev, KERN_WARNING,
"ACPI: failed the second time, disabled\n");
dev->acpi_handle = NULL; dev->acpi_handle = NULL;
/* if port is working, request IDENTIFY reload and continue */ /* We can safely continue if no _GTF command has been executed
if (!(ap->pflags & ATA_PFLAG_FROZEN)) * and port is not frozen.
rc = 1; */
} if (!nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN))
dev->flags |= ATA_DFLAG_ACPI_FAILED; return 0;
return rc; return rc;
} }
/**
* ata_acpi_on_disable - ATA ACPI hook called when a device is disabled
* @dev: target ATA device
*
* This function is called when @dev is about to be disabled.
*
* LOCKING:
* EH context.
*/
void ata_acpi_on_disable(struct ata_device *dev)
{
ata_acpi_clear_gtf(dev);
}
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <linux/cdrom.h>
#include "libata.h" #include "libata.h"
...@@ -622,6 +623,7 @@ void ata_dev_disable(struct ata_device *dev) ...@@ -622,6 +623,7 @@ void ata_dev_disable(struct ata_device *dev)
if (ata_dev_enabled(dev)) { if (ata_dev_enabled(dev)) {
if (ata_msg_drv(dev->link->ap)) if (ata_msg_drv(dev->link->ap))
ata_dev_printk(dev, KERN_WARNING, "disabled\n"); ata_dev_printk(dev, KERN_WARNING, "disabled\n");
ata_acpi_on_disable(dev);
ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 |
ATA_DNXFER_QUIET); ATA_DNXFER_QUIET);
dev->class++; dev->class++;
...@@ -3923,6 +3925,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes) ...@@ -3923,6 +3925,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes)
/* clear SError */ /* clear SError */
if (sata_scr_read(link, SCR_ERROR, &serror) == 0) if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
sata_scr_write(link, SCR_ERROR, serror); sata_scr_write(link, SCR_ERROR, serror);
link->eh_info.serror = 0;
/* is double-select really necessary? */ /* is double-select really necessary? */
if (classes[0] != ATA_DEV_NONE) if (classes[0] != ATA_DEV_NONE)
...@@ -4149,6 +4152,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ...@@ -4149,6 +4152,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "HITACHI HDS7250SASUN500G*", NULL, ATA_HORKAGE_NONCQ }, { "HITACHI HDS7250SASUN500G*", NULL, ATA_HORKAGE_NONCQ },
{ "HITACHI HDS7225SBSUN250G*", NULL, ATA_HORKAGE_NONCQ }, { "HITACHI HDS7225SBSUN250G*", NULL, ATA_HORKAGE_NONCQ },
{ "ST380817AS", "3.42", ATA_HORKAGE_NONCQ }, { "ST380817AS", "3.42", ATA_HORKAGE_NONCQ },
{ "ST3160023AS", "3.42", ATA_HORKAGE_NONCQ },
/* Blacklist entries taken from Silicon Image 3124/3132 /* Blacklist entries taken from Silicon Image 3124/3132
Windows driver .inf file - also several Linux problem reports */ Windows driver .inf file - also several Linux problem reports */
...@@ -4648,6 +4652,43 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) ...@@ -4648,6 +4652,43 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
return 0; return 0;
} }
/**
* atapi_qc_may_overflow - Check whether data transfer may overflow
* @qc: ATA command in question
*
* ATAPI commands which transfer variable length data to host
* might overflow due to application error or hardare bug. This
* function checks whether overflow should be drained and ignored
* for @qc.
*
* LOCKING:
* None.
*
* RETURNS:
* 1 if @qc may overflow; otherwise, 0.
*/
static int atapi_qc_may_overflow(struct ata_queued_cmd *qc)
{
if (qc->tf.protocol != ATA_PROT_ATAPI &&
qc->tf.protocol != ATA_PROT_ATAPI_DMA)
return 0;
if (qc->tf.flags & ATA_TFLAG_WRITE)
return 0;
switch (qc->cdb[0]) {
case READ_10:
case READ_12:
case WRITE_10:
case WRITE_12:
case GPCMD_READ_CD:
case GPCMD_READ_CD_MSF:
return 0;
}
return 1;
}
/** /**
* ata_std_qc_defer - Check whether a qc needs to be deferred * ata_std_qc_defer - Check whether a qc needs to be deferred
* @qc: ATA command in question * @qc: ATA command in question
...@@ -5136,23 +5177,19 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) ...@@ -5136,23 +5177,19 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
* Inherited from caller. * Inherited from caller.
* *
*/ */
static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
{ {
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
struct scatterlist *sg = qc->__sg;
struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct ata_eh_info *ehi = &qc->dev->link->eh_info;
struct scatterlist *sg;
struct page *page; struct page *page;
unsigned char *buf; unsigned char *buf;
unsigned int offset, count; unsigned int offset, count;
int no_more_sg = 0;
if (qc->curbytes + bytes >= qc->nbytes)
ap->hsm_task_state = HSM_ST_LAST;
next_sg: next_sg:
if (unlikely(no_more_sg)) { sg = qc->cursg;
if (unlikely(!sg)) {
/* /*
* The end of qc->sg is reached and the device expects * The end of qc->sg is reached and the device expects
* more data to transfer. In order not to overrun qc->sg * more data to transfer. In order not to overrun qc->sg
...@@ -5161,21 +5198,28 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) ...@@ -5161,21 +5198,28 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
* - for write case, padding zero data to the device * - for write case, padding zero data to the device
*/ */
u16 pad_buf[1] = { 0 }; u16 pad_buf[1] = { 0 };
unsigned int words = bytes >> 1;
unsigned int i; unsigned int i;
if (words) /* warning if bytes > 1 */ if (bytes > qc->curbytes - qc->nbytes + ATAPI_MAX_DRAIN) {
ata_dev_printk(qc->dev, KERN_WARNING, ata_ehi_push_desc(ehi, "too much trailing data "
"%u bytes trailing data\n", bytes); "buf=%u cur=%u bytes=%u",
qc->nbytes, qc->curbytes, bytes);
return -1;
}
/* overflow is exptected for misc ATAPI commands */
if (bytes && !atapi_qc_may_overflow(qc))
ata_dev_printk(qc->dev, KERN_WARNING, "ATAPI %u bytes "
"trailing data (cdb=%02x nbytes=%u)\n",
bytes, qc->cdb[0], qc->nbytes);
for (i = 0; i < words; i++) for (i = 0; i < (bytes + 1) / 2; i++)
ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write); ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write);
ap->hsm_task_state = HSM_ST_LAST; qc->curbytes += bytes;
return;
}
sg = qc->cursg; return 0;
}
page = sg_page(sg); page = sg_page(sg);
offset = sg->offset + qc->cursg_ofs; offset = sg->offset + qc->cursg_ofs;
...@@ -5210,19 +5254,20 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) ...@@ -5210,19 +5254,20 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
} }
bytes -= count; bytes -= count;
if ((count & 1) && bytes)
bytes--;
qc->curbytes += count; qc->curbytes += count;
qc->cursg_ofs += count; qc->cursg_ofs += count;
if (qc->cursg_ofs == sg->length) { if (qc->cursg_ofs == sg->length) {
if (qc->cursg == lsg)
no_more_sg = 1;
qc->cursg = sg_next(qc->cursg); qc->cursg = sg_next(qc->cursg);
qc->cursg_ofs = 0; qc->cursg_ofs = 0;
} }
if (bytes) if (bytes)
goto next_sg; goto next_sg;
return 0;
} }
/** /**
...@@ -5265,7 +5310,8 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) ...@@ -5265,7 +5310,8 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
__atapi_pio_bytes(qc, bytes); if (__atapi_pio_bytes(qc, bytes))
goto err_out;
ata_altstatus(ap); /* flush */ ata_altstatus(ap); /* flush */
return; return;
...@@ -7208,18 +7254,14 @@ static void ata_port_detach(struct ata_port *ap) ...@@ -7208,18 +7254,14 @@ static void ata_port_detach(struct ata_port *ap)
ata_port_wait_eh(ap); ata_port_wait_eh(ap);
/* EH is now guaranteed to see UNLOADING, so no new device /* EH is now guaranteed to see UNLOADING - EH context belongs
* will be attached. Disable all existing devices. * to us. Disable all existing devices.
*/ */
spin_lock_irqsave(ap->lock, flags);
ata_port_for_each_link(link, ap) { ata_port_for_each_link(link, ap) {
ata_link_for_each_dev(dev, link) ata_link_for_each_dev(dev, link)
ata_dev_disable(dev); ata_dev_disable(dev);
} }
spin_unlock_irqrestore(ap->lock, flags);
/* Final freeze & EH. All in-flight commands are aborted. EH /* Final freeze & EH. All in-flight commands are aborted. EH
* will be skipped and retrials will be terminated with bad * will be skipped and retrials will be terminated with bad
* target. * target.
...@@ -7251,6 +7293,9 @@ void ata_host_detach(struct ata_host *host) ...@@ -7251,6 +7293,9 @@ void ata_host_detach(struct ata_host *host)
for (i = 0; i < host->n_ports; i++) for (i = 0; i < host->n_ports; i++)
ata_port_detach(host->ports[i]); ata_port_detach(host->ports[i]);
/* the host is dead now, dissociate ACPI */
ata_acpi_dissociate(host);
} }
/** /**
......
...@@ -1264,8 +1264,8 @@ static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc) ...@@ -1264,8 +1264,8 @@ static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc)
tf.feature |= ATAPI_PKT_DMA; tf.feature |= ATAPI_PKT_DMA;
} else { } else {
tf.protocol = ATA_PROT_ATAPI; tf.protocol = ATA_PROT_ATAPI;
tf.lbam = (8 * 1024) & 0xff; tf.lbam = SCSI_SENSE_BUFFERSIZE;
tf.lbah = (8 * 1024) >> 8; tf.lbah = 0;
} }
return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE, return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE,
......
...@@ -108,15 +108,19 @@ extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm); ...@@ -108,15 +108,19 @@ extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
#ifdef CONFIG_ATA_ACPI #ifdef CONFIG_ATA_ACPI
extern void ata_acpi_associate_sata_port(struct ata_port *ap); extern void ata_acpi_associate_sata_port(struct ata_port *ap);
extern void ata_acpi_associate(struct ata_host *host); extern void ata_acpi_associate(struct ata_host *host);
extern void ata_acpi_dissociate(struct ata_host *host);
extern int ata_acpi_on_suspend(struct ata_port *ap); extern int ata_acpi_on_suspend(struct ata_port *ap);
extern void ata_acpi_on_resume(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap);
extern int ata_acpi_on_devcfg(struct ata_device *adev); extern int ata_acpi_on_devcfg(struct ata_device *dev);
extern void ata_acpi_on_disable(struct ata_device *dev);
#else #else
static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { } static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { }
static inline void ata_acpi_associate(struct ata_host *host) { } static inline void ata_acpi_associate(struct ata_host *host) { }
static inline void ata_acpi_dissociate(struct ata_host *host) { }
static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
static inline void ata_acpi_on_resume(struct ata_port *ap) { } static inline void ata_acpi_on_resume(struct ata_port *ap) { }
static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; }
static inline void ata_acpi_on_disable(struct ata_device *dev) { }
#endif #endif
/* libata-scsi.c */ /* libata-scsi.c */
......
...@@ -2506,11 +2506,31 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) ...@@ -2506,11 +2506,31 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
if (pdev->vendor == PCI_VENDOR_ID_TTI && if (pdev->vendor == PCI_VENDOR_ID_TTI &&
(pdev->device == 0x2300 || pdev->device == 0x2310)) (pdev->device == 0x2300 || pdev->device == 0x2310))
{ {
printk(KERN_WARNING "sata_mv: Highpoint RocketRAID BIOS" /*
" will CORRUPT DATA on attached drives when" * Highpoint RocketRAID PCIe 23xx series cards:
" configured as \"Legacy\". BEWARE!\n"); *
printk(KERN_WARNING "sata_mv: Use BIOS \"JBOD\" volumes" * Unconfigured drives are treated as "Legacy"
" instead for safety.\n"); * by the BIOS, and it overwrites sector 8 with
* a "Lgcy" metadata block prior to Linux boot.
*
* Configured drives (RAID or JBOD) leave sector 8
* alone, but instead overwrite a high numbered
* sector for the RAID metadata. This sector can
* be determined exactly, by truncating the physical
* drive capacity to a nice even GB value.
*
* RAID metadata is at: (dev->n_sectors & ~0xfffff)
*
* Warn the user, lest they think we're just buggy.
*/
printk(KERN_WARNING DRV_NAME ": Highpoint RocketRAID"
" BIOS CORRUPTS DATA on all attached drives,"
" regardless of if/how they are configured."
" BEWARE!\n");
printk(KERN_WARNING DRV_NAME ": For data safety, do not"
" use sectors 8-9 on \"Legacy\" drives,"
" and avoid the final two gigabytes on"
" all RocketRAID BIOS initialized drives.\n");
} }
case chip_6042: case chip_6042:
hpriv->ops = &mv6xxx_ops; hpriv->ops = &mv6xxx_ops;
......
...@@ -390,23 +390,19 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) ...@@ -390,23 +390,19 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
sil_scr_read(ap, SCR_ERROR, &serror); sil_scr_read(ap, SCR_ERROR, &serror);
sil_scr_write(ap, SCR_ERROR, serror); sil_scr_write(ap, SCR_ERROR, serror);
/* Trigger hotplug and accumulate SError only if the /* Sometimes spurious interrupts occur, double check
* port isn't already frozen. Otherwise, PHY events * it's PHYRDY CHG.
* during hardreset makes controllers with broken SIEN
* repeat probing needlessly.
*/ */
if (!(ap->pflags & ATA_PFLAG_FROZEN)) { if (serror & SERR_PHYRDY_CHG) {
ata_ehi_hotplugged(&ap->link.eh_info);
ap->link.eh_info.serror |= serror; ap->link.eh_info.serror |= serror;
}
goto freeze; goto freeze;
} }
if (unlikely(!qc)) if (!(bmdma2 & SIL_DMA_COMPLETE))
goto freeze; return;
}
if (unlikely(qc->tf.flags & ATA_TFLAG_POLLING)) { if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
/* this sometimes happens, just clear IRQ */ /* this sometimes happens, just clear IRQ */
ata_chk_status(ap); ata_chk_status(ap);
return; return;
......
...@@ -190,6 +190,8 @@ enum { ...@@ -190,6 +190,8 @@ enum {
ATA_CMD_READ_LOG_EXT = 0x2f, ATA_CMD_READ_LOG_EXT = 0x2f,
ATA_CMD_PMP_READ = 0xE4, ATA_CMD_PMP_READ = 0xE4,
ATA_CMD_PMP_WRITE = 0xE8, ATA_CMD_PMP_WRITE = 0xE8,
ATA_CMD_CONF_OVERLAY = 0xB1,
ATA_CMD_SEC_FREEZE_LOCK = 0xF5,
/* READ_LOG_EXT pages */ /* READ_LOG_EXT pages */
ATA_LOG_SATA_NCQ = 0x10, ATA_LOG_SATA_NCQ = 0x10,
...@@ -239,6 +241,19 @@ enum { ...@@ -239,6 +241,19 @@ enum {
SATA_AN = 0x05, /* Asynchronous Notification */ SATA_AN = 0x05, /* Asynchronous Notification */
SATA_DIPM = 0x03, /* Device Initiated Power Management */ SATA_DIPM = 0x03, /* Device Initiated Power Management */
/* feature values for SET_MAX */
ATA_SET_MAX_ADDR = 0x00,
ATA_SET_MAX_PASSWD = 0x01,
ATA_SET_MAX_LOCK = 0x02,
ATA_SET_MAX_UNLOCK = 0x03,
ATA_SET_MAX_FREEZE_LOCK = 0x04,
/* feature values for DEVICE CONFIGURATION OVERLAY */
ATA_DCO_RESTORE = 0xC0,
ATA_DCO_FREEZE_LOCK = 0xC1,
ATA_DCO_IDENTIFY = 0xC2,
ATA_DCO_SET = 0xC3,
/* ATAPI stuff */ /* ATAPI stuff */
ATAPI_PKT_DMA = (1 << 0), ATAPI_PKT_DMA = (1 << 0),
ATAPI_DMADIR = (1 << 2), /* ATAPI data dir: ATAPI_DMADIR = (1 << 2), /* ATAPI data dir:
......
...@@ -119,6 +119,8 @@ enum { ...@@ -119,6 +119,8 @@ enum {
ATA_DEF_BUSY_WAIT = 10000, ATA_DEF_BUSY_WAIT = 10000,
ATA_SHORT_PAUSE = (HZ >> 6) + 1, ATA_SHORT_PAUSE = (HZ >> 6) + 1,
ATAPI_MAX_DRAIN = 16 << 10,
ATA_SHT_EMULATED = 1, ATA_SHT_EMULATED = 1,
ATA_SHT_CMD_PER_LUN = 1, ATA_SHT_CMD_PER_LUN = 1,
ATA_SHT_THIS_ID = -1, ATA_SHT_THIS_ID = -1,
...@@ -211,7 +213,7 @@ enum { ...@@ -211,7 +213,7 @@ enum {
ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */ ATA_PFLAG_INIT_GTM_VALID = (1 << 19), /* initial gtm data valid */
/* struct ata_queued_cmd flags */ /* struct ata_queued_cmd flags */
ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */
...@@ -498,6 +500,7 @@ struct ata_device { ...@@ -498,6 +500,7 @@ struct ata_device {
struct scsi_device *sdev; /* attached SCSI device */ struct scsi_device *sdev; /* attached SCSI device */
#ifdef CONFIG_ATA_ACPI #ifdef CONFIG_ATA_ACPI
acpi_handle acpi_handle; acpi_handle acpi_handle;
union acpi_object *gtf_cache;
#endif #endif
/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
u64 n_sectors; /* size of device, if ATA */ u64 n_sectors; /* size of device, if ATA */
...@@ -653,7 +656,7 @@ struct ata_port { ...@@ -653,7 +656,7 @@ struct ata_port {
#ifdef CONFIG_ATA_ACPI #ifdef CONFIG_ATA_ACPI
acpi_handle acpi_handle; acpi_handle acpi_handle;
struct ata_acpi_gtm acpi_gtm; struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
#endif #endif
u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */
}; };
...@@ -939,10 +942,20 @@ enum { ...@@ -939,10 +942,20 @@ enum {
/* libata-acpi.c */ /* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI #ifdef CONFIG_ATA_ACPI
static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap)
{
if (ap->pflags & ATA_PFLAG_INIT_GTM_VALID)
return &ap->__acpi_init_gtm;
return NULL;
}
extern int ata_acpi_cbl_80wire(struct ata_port *ap); extern int ata_acpi_cbl_80wire(struct ata_port *ap);
int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm); int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm);
int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *stm); int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm);
#else #else
static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap)
{
return NULL;
}
static inline int ata_acpi_cbl_80wire(struct ata_port *ap) { return 0; } static inline int ata_acpi_cbl_80wire(struct ata_port *ap) { return 0; }
#endif #endif
...@@ -1013,18 +1026,18 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -1013,18 +1026,18 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
* printk helpers * printk helpers
*/ */
#define ata_port_printk(ap, lv, fmt, args...) \ #define ata_port_printk(ap, lv, fmt, args...) \
printk(lv"ata%u: "fmt, (ap)->print_id , ##args) printk("%sata%u: "fmt, lv, (ap)->print_id , ##args)
#define ata_link_printk(link, lv, fmt, args...) do { \ #define ata_link_printk(link, lv, fmt, args...) do { \
if ((link)->ap->nr_pmp_links) \ if ((link)->ap->nr_pmp_links) \
printk(lv"ata%u.%02u: "fmt, (link)->ap->print_id, \ printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \ (link)->pmp , ##args); \
else \ else \
printk(lv"ata%u: "fmt, (link)->ap->print_id , ##args); \ printk("%sata%u: "fmt, lv, (link)->ap->print_id , ##args); \
} while(0) } while(0)
#define ata_dev_printk(dev, lv, fmt, args...) \ #define ata_dev_printk(dev, lv, fmt, args...) \
printk(lv"ata%u.%02u: "fmt, (dev)->link->ap->print_id, \ printk("%sata%u.%02u: "fmt, lv, (dev)->link->ap->print_id, \
(dev)->link->pmp + (dev)->devno , ##args) (dev)->link->pmp + (dev)->devno , ##args)
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment