Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ededa4d3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
Loading
Loading
Loading
Loading
+270 −117
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 * Copyright (C) 2006 Randy Dunlap
 */

#include <linux/module.h>
#include <linux/ata.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -25,6 +26,18 @@
#include <acpi/acmacros.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 SATA_ADR(root, pmp)	(((root) << 16) | (pmp))

@@ -41,6 +54,12 @@ 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_acpi_associate_sata_port - associate SATA port with ACPI objects
 * @ap: target SATA port
@@ -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);
	}

	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,
@@ -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
 * @ap: target ATA port
@@ -200,7 +248,7 @@ void ata_acpi_associate(struct ata_host *host)
 * RETURNS:
 * 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 };
	union acpi_object *out_obj;
@@ -259,15 +307,16 @@ EXPORT_SYMBOL_GPL(ata_acpi_gtm);
 * RETURNS:
 * 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;
	struct ata_acpi_gtm		stm_buf = *stm;
	struct acpi_object_list         input;
	union acpi_object               in_params[3];

	in_params[0].type = ACPI_TYPE_BUFFER;
	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 ? */
	in_params[1].type = ACPI_TYPE_BUFFER;
	in_params[1].buffer.length = 512;
@@ -297,7 +346,6 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
 * ata_dev_get_GTF - get the drive bootup default taskfile settings
 * @dev: target ATA device
 * @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.
 *
@@ -311,11 +359,10 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
 * EH context.
 *
 * RETURNS:
 * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
 * contain valid data.
 * Number of taskfiles on success, 0 if _GTF doesn't exist.  -EINVAL
 * if _GTF is invalid.
 */
static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
			   void **ptr_to_free)
static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf)
{
	struct ata_port *ap = dev->link->ap;
	acpi_status status;
@@ -323,6 +370,12 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
	union acpi_object *out_obj;
	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 */
	output.length = ACPI_ALLOCATE_BUFFER;
	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,

	/* _GTF has no input parameters */
	status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
	out_obj = dev->gtf_cache = output.pointer;

	if (ACPI_FAILURE(status)) {
		if (status != AE_NOT_FOUND) {
			ata_dev_printk(dev, KERN_WARNING,
				       "_GTF evaluation failed (AE 0x%x)\n",
				       status);
			rc = -EINVAL;
		}
		goto out_free;
	}
@@ -350,14 +405,15 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
				__FUNCTION__,
				(unsigned long long)output.length,
				output.pointer);
		rc = -EINVAL;
		goto out_free;
	}

	out_obj = output.pointer;
	if (out_obj->type != ACPI_TYPE_BUFFER) {
		ata_dev_printk(dev, KERN_WARNING,
			       "_GTF unexpected object type 0x%x\n",
			       out_obj->type);
		rc = -EINVAL;
		goto out_free;
	}

@@ -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,
			       "unexpected _GTF length (%d)\n",
			       out_obj->buffer.length);
		rc = -EINVAL;
		goto out_free;
	}

	*ptr_to_free = out_obj;
	*gtf = (void *)out_obj->buffer.pointer;
 done:
	rc = out_obj->buffer.length / REGS_PER_GTF;

	if (gtf) {
		*gtf = (void *)out_obj->buffer.pointer;
		if (ata_msg_probe(ap))
		ata_dev_printk(dev, KERN_DEBUG, "%s: returning "
			"gtf=%p, gtf_count=%d, ptr_to_free=%p\n",
			__FUNCTION__, *gtf, rc, *ptr_to_free);
			ata_dev_printk(dev, KERN_DEBUG,
				       "%s: returning gtf=%p, gtf_count=%d\n",
				       __FUNCTION__, *gtf, rc);
	}
	return rc;

 out_free:
	kfree(output.pointer);
	ata_acpi_clear_gtf(dev);
	return rc;
}

@@ -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)
{
	struct ata_acpi_gtm gtm;
	const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
	int valid = 0;

	/* No _GTM data, no information */
	if (ata_acpi_gtm(ap, &gtm) < 0)
	if (!gtm)
		return 0;

	/* 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;
	if ((gtm.flags & 0x14) == 0x14 && gtm.drive[1].dma < 55)
	if ((gtm->flags & 0x14) == 0x14 && gtm->drive[1].dma < 55)
		valid |= 2;
	/* 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;
	if ((gtm.flags & 0x14) == 0x04 && gtm.drive[0].dma < 55)
	if ((gtm->flags & 0x14) == 0x04 && gtm->drive[0].dma < 55)
		valid |= 2;

	/* Drive check */
@@ -421,8 +478,62 @@ int ata_acpi_cbl_80wire(struct ata_port *ap)

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
 * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
 *
@@ -441,56 +552,77 @@ EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
 * EH context.
 *
 * 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,
			      const struct ata_acpi_gtf *gtf)
static int ata_acpi_run_tf(struct ata_device *dev,
			   const struct ata_acpi_gtf *gtf,
			   const struct ata_acpi_gtf *prev_gtf)
{
	struct ata_port *ap = dev->link->ap;
	struct ata_taskfile tf, rtf;
	struct ata_taskfile *pptf = NULL;
	struct ata_taskfile tf, ptf, rtf;
	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)
	    && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
	    && (gtf->tf[6] == 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 */
	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
	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 */
	if (!ata_acpi_filter_tf(&tf, pptf)) {
		rtf = tf;
		err_mask = ata_exec_internal(dev, &rtf, NULL,
					     DMA_NONE, NULL, 0, 0);

	if (ata_msg_probe(ap))
		ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd "
			       "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n",
			       tf.command, tf.feature, tf.nsect,
			       tf.lbal, tf.lbam, tf.lbah, tf.device);
		switch (err_mask) {
		case 0:
			level = KERN_DEBUG;
			snprintf(msg, sizeof(msg), "succeeded");
			rc = 1;
			break;

	rtf = tf;
	err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0, 0);
	if (err_mask) {
		ata_dev_printk(dev, KERN_ERR,
			"ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed "
			"(Emask=0x%x Stat=0x%02x Err=0x%02x)\n",
			tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam,
			tf.lbah, tf.device, err_mask, rtf.command, rtf.feature);
		return -EIO;
		case AC_ERR_DEV:
			level = KERN_INFO;
			snprintf(msg, sizeof(msg),
				 "rejected by device (Stat=0x%02x Err=0x%02x)",
				 rtf.command, rtf.feature);
			rc = 0;
			break;

		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
 * @dev: target ATA device
 * @nr_executed: out paramter for the number of executed commands
 *
 * Evaluate _GTF and excute returned taskfiles.
 *
@@ -498,35 +630,36 @@ static int taskfile_load_raw(struct ata_device *dev,
 * EH context.
 *
 * RETURNS:
 * Number of executed taskfiles on success, 0 if _GTF doesn't exist or
 * doesn't contain valid data.  -errno on other errors.
 * Number of executed taskfiles on success, 0 if _GTF doesn't exist.
 * -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;
	void *ptr_to_free = NULL;
	struct ata_acpi_gtf *gtf = NULL, *pgtf = NULL;
	int gtf_count, i, rc;

	/* 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 */
	for (i = 0, rc = 0; i < gtf_count; i++) {
		int tmp;

		/* ACPI errors are eventually ignored.  Run till the
		 * end even after errors.
		 */
		tmp = taskfile_load_raw(dev, gtf++);
		if (!rc)
			rc = tmp;
	for (i = 0; i < gtf_count; i++, gtf++) {
		rc = ata_acpi_run_tf(dev, gtf, pgtf);
		if (rc < 0)
			break;
		if (rc) {
			(*nr_executed)++;
			pgtf = gtf;
		}
	}

	kfree(ptr_to_free);
	ata_acpi_clear_gtf(dev);

	if (rc == 0)
		return gtf_count;
	if (rc < 0)
		return rc;
	return 0;
}

/**
@@ -596,27 +729,8 @@ static int ata_acpi_push_id(struct ata_device *dev)
 */
int ata_acpi_on_suspend(struct ata_port *ap)
{
	unsigned long flags;
	int rc;

	/* proceed iff per-port acpi_handle is valid */
	if (!ap->acpi_handle)
	/* nada */
	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,19 +745,35 @@ int ata_acpi_on_suspend(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;

	if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) {
		BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
	if (ap->acpi_handle && gtm) {
		/* _GTM valid */

		/* restore timing parameters */
		ata_acpi_stm(ap, &ap->acpi_gtm);
	}
		ata_acpi_stm(ap, gtm);

	/* schedule _GTF */
	ata_link_for_each_dev(dev, &ap->link)
		/* _GTF should immediately follow _STM so that it can
		 * 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;
		}
	} 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;
		}
	}
}

/**
 * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration
@@ -664,6 +794,7 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
	struct ata_port *ap = dev->link->ap;
	struct ata_eh_context *ehc = &ap->link.eh_context;
	int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
	int nr_executed = 0;
	int rc;

	if (!dev->acpi_handle)
@@ -682,14 +813,14 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
	}

	/* do _GTF */
	rc = ata_acpi_exec_tfs(dev);
	if (rc < 0)
	rc = ata_acpi_exec_tfs(dev, &nr_executed);
	if (rc)
		goto acpi_err;

	dev->flags &= ~ATA_DFLAG_ACPI_PENDING;

	/* refresh IDENTIFY page if any _GTF command has been executed */
	if (rc > 0) {
	if (nr_executed) {
		rc = ata_dev_reread_id(dev, 0);
		if (rc < 0) {
			ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY "
@@ -701,17 +832,39 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
	return 0;

 acpi_err:
	/* let EH retry on the first failure, disable ACPI on the second */
	if (dev->flags & ATA_DFLAG_ACPI_FAILED) {
		ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the "
			       "second time, disabling (errno=%d)\n", rc);
	/* ignore evaluation failure if we can continue safely */
	if (rc == -EINVAL && !nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN))
		return 0;

	/* 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;

		/* if port is working, request IDENTIFY reload and continue */
		if (!(ap->pflags & ATA_PFLAG_FROZEN))
			rc = 1;
	}
	dev->flags |= ATA_DFLAG_ACPI_FAILED;
	/* We can safely continue if no _GTF command has been executed
	 * and port is not frozen.
	 */
	if (!nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN))
		return 0;

	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);
}
+73 −28
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@
#include <linux/libata.h>
#include <asm/semaphore.h>
#include <asm/byteorder.h>
#include <linux/cdrom.h>

#include "libata.h"

@@ -622,6 +623,7 @@ void ata_dev_disable(struct ata_device *dev)
	if (ata_dev_enabled(dev)) {
		if (ata_msg_drv(dev->link->ap))
			ata_dev_printk(dev, KERN_WARNING, "disabled\n");
		ata_acpi_on_disable(dev);
		ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 |
					     ATA_DNXFER_QUIET);
		dev->class++;
@@ -3923,6 +3925,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes)
	/* clear SError */
	if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
		sata_scr_write(link, SCR_ERROR, serror);
	link->eh_info.serror = 0;

	/* is double-select really necessary? */
	if (classes[0] != ATA_DEV_NONE)
@@ -4149,6 +4152,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
	{ "HITACHI HDS7250SASUN500G*", NULL,    ATA_HORKAGE_NONCQ },
	{ "HITACHI HDS7225SBSUN250G*", NULL,    ATA_HORKAGE_NONCQ },
	{ "ST380817AS",		"3.42",		ATA_HORKAGE_NONCQ },
	{ "ST3160023AS",	"3.42",		ATA_HORKAGE_NONCQ },

	/* Blacklist entries taken from Silicon Image 3124/3132
	   Windows driver .inf file - also several Linux problem reports */
@@ -4648,6 +4652,43 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
	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
 *	@qc: ATA command in question
@@ -5136,23 +5177,19 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
 *	Inherited from caller.
 *
 */

static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
{
	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_eh_info *ehi = &qc->dev->link->eh_info;
	struct scatterlist *sg;
	struct page *page;
	unsigned char *buf;
	unsigned int offset, count;
	int no_more_sg = 0;

	if (qc->curbytes + bytes >= qc->nbytes)
		ap->hsm_task_state = HSM_ST_LAST;

next_sg:
	if (unlikely(no_more_sg)) {
	sg = qc->cursg;
	if (unlikely(!sg)) {
		/*
		 * The end of qc->sg is reached and the device expects
		 * more data to transfer. In order not to overrun qc->sg
@@ -5161,21 +5198,28 @@ next_sg:
		 *    - for write case, padding zero data to the device
		 */
		u16 pad_buf[1] = { 0 };
		unsigned int words = bytes >> 1;
		unsigned int i;

		if (words) /* warning if bytes > 1 */
			ata_dev_printk(qc->dev, KERN_WARNING,
				       "%u bytes trailing data\n", bytes);
		if (bytes > qc->curbytes - qc->nbytes + ATAPI_MAX_DRAIN) {
			ata_ehi_push_desc(ehi, "too much trailing data "
					  "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->hsm_task_state = HSM_ST_LAST;
		return;
	}
		qc->curbytes += bytes;

	sg = qc->cursg;
		return 0;
	}

	page = sg_page(sg);
	offset = sg->offset + qc->cursg_ofs;
@@ -5210,19 +5254,20 @@ next_sg:
	}

	bytes -= count;
	if ((count & 1) && bytes)
		bytes--;
	qc->curbytes += count;
	qc->cursg_ofs += count;

	if (qc->cursg_ofs == sg->length) {
		if (qc->cursg == lsg)
			no_more_sg = 1;

		qc->cursg = sg_next(qc->cursg);
		qc->cursg_ofs = 0;
	}

	if (bytes)
		goto next_sg;

	return 0;
}

/**
@@ -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);

	__atapi_pio_bytes(qc, bytes);
	if (__atapi_pio_bytes(qc, bytes))
		goto err_out;
	ata_altstatus(ap); /* flush */

	return;
@@ -7208,18 +7254,14 @@ static void ata_port_detach(struct ata_port *ap)

	ata_port_wait_eh(ap);

	/* EH is now guaranteed to see UNLOADING, so no new device
	 * will be attached.  Disable all existing devices.
	/* EH is now guaranteed to see UNLOADING - EH context belongs
	 * to us.  Disable all existing devices.
	 */
	spin_lock_irqsave(ap->lock, flags);

	ata_port_for_each_link(link, ap) {
		ata_link_for_each_dev(dev, link)
			ata_dev_disable(dev);
	}

	spin_unlock_irqrestore(ap->lock, flags);

	/* Final freeze & EH.  All in-flight commands are aborted.  EH
	 * will be skipped and retrials will be terminated with bad
	 * target.
@@ -7251,6 +7293,9 @@ void ata_host_detach(struct ata_host *host)

	for (i = 0; i < host->n_ports; i++)
		ata_port_detach(host->ports[i]);

	/* the host is dead now, dissociate ACPI */
	ata_acpi_dissociate(host);
}

/**
+2 −2
Original line number Diff line number Diff line
@@ -1264,8 +1264,8 @@ static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc)
		tf.feature |= ATAPI_PKT_DMA;
	} else {
		tf.protocol = ATA_PROT_ATAPI;
		tf.lbam = (8 * 1024) & 0xff;
		tf.lbah = (8 * 1024) >> 8;
		tf.lbam = SCSI_SENSE_BUFFERSIZE;
		tf.lbah = 0;
	}

	return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE,
+6 −2
Original line number Diff line number Diff line
@@ -108,15 +108,19 @@ extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
#ifdef CONFIG_ATA_ACPI
extern void ata_acpi_associate_sata_port(struct ata_port *ap);
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 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
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_dissociate(struct ata_host *host) { }
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 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

/* libata-scsi.c */
+25 −5
Original line number Diff line number Diff line
@@ -2506,11 +2506,31 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
		if (pdev->vendor == PCI_VENDOR_ID_TTI &&
		    (pdev->device == 0x2300 || pdev->device == 0x2310))
		{
			printk(KERN_WARNING "sata_mv: Highpoint RocketRAID BIOS"
				" will CORRUPT DATA on attached drives when"
				" configured as \"Legacy\".  BEWARE!\n");
			printk(KERN_WARNING "sata_mv: Use BIOS \"JBOD\" volumes"
				" instead for safety.\n");
			/*
			 * Highpoint RocketRAID PCIe 23xx series cards:
			 *
			 * Unconfigured drives are treated as "Legacy"
			 * 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:
		hpriv->ops = &mv6xxx_ops;
Loading