/*
 * libata-acpi.c
 * Provides ACPI support for PATA/SATA.
 *
 * Copyright (C) 2006 Intel Corp.
 * Copyright (C) 2006 Randy Dunlap
 */

#include <linux/ata.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/libata.h>
#include <linux/pci.h>
#include "libata.h"

#include <acpi/acpi_bus.h>
#include <acpi/acnames.h>
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
#include <acpi/acexcep.h>
#include <acpi/acmacros.h>
#include <acpi/actypes.h>

#define SATA_ROOT_PORT(x)	(((x) >> 16) & 0xffff)
#define SATA_PORT_NUMBER(x)	((x) & 0xffff)	/* or NO_PORT_MULT */
#define NO_PORT_MULT		0xffff
#define SATA_ADR_RSVD		0xffffffff

#define REGS_PER_GTF		7
struct taskfile_array {
	u8	tfa[REGS_PER_GTF];	/* regs. 0x1f1 - 0x1f7 */
};

/*
 *	Helper - belongs in the PCI layer somewhere eventually
 */
static int is_pci_dev(struct device *dev)
{
	return (dev->bus == &pci_bus_type);
}

/**
 * sata_get_dev_handle - finds acpi_handle and PCI device.function
 * @dev: device to locate
 * @handle: returned acpi_handle for @dev
 * @pcidevfn: return PCI device.func for @dev
 *
 * This function is somewhat SATA-specific.  Or at least the
 * PATA & SATA versions of this function are different,
 * so it's not entirely generic code.
 *
 * Returns 0 on success, <0 on error.
 */
static int sata_get_dev_handle(struct device *dev, acpi_handle *handle,
					acpi_integer *pcidevfn)
{
	struct pci_dev	*pci_dev;
	acpi_integer	addr;

	if (!is_pci_dev(dev))
		return -ENODEV;

	pci_dev = to_pci_dev(dev);	/* NOTE: PCI-specific */
	/* Please refer to the ACPI spec for the syntax of _ADR. */
	addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
	*pcidevfn = addr;
	*handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
	if (!*handle)
		return -ENODEV;
	return 0;
}

/**
 * pata_get_dev_handle - finds acpi_handle and PCI device.function
 * @dev: device to locate
 * @handle: returned acpi_handle for @dev
 * @pcidevfn: return PCI device.func for @dev
 *
 * The PATA and SATA versions of this function are different.
 *
 * Returns 0 on success, <0 on error.
 */
static int pata_get_dev_handle(struct device *dev, acpi_handle *handle,
				acpi_integer *pcidevfn)
{
	unsigned int bus, devnum, func;
	acpi_integer addr;
	acpi_handle dev_handle, parent_handle;
	struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
					.pointer = NULL};
	acpi_status status;
	struct acpi_device_info	*dinfo = NULL;
	int ret = -ENODEV;
	struct pci_dev *pdev;

	if (!is_pci_dev(dev))
		return -ENODEV;

	pdev = to_pci_dev(dev);

	bus = pdev->bus->number;
	devnum = PCI_SLOT(pdev->devfn);
	func = PCI_FUNC(pdev->devfn);

	dev_handle = DEVICE_ACPI_HANDLE(dev);
	parent_handle = DEVICE_ACPI_HANDLE(dev->parent);

	status = acpi_get_object_info(parent_handle, &buffer);
	if (ACPI_FAILURE(status))
		goto err;

	dinfo = buffer.pointer;
	if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
	    dinfo->address == bus) {
		/* ACPI spec for _ADR for PCI bus: */
		addr = (acpi_integer)(devnum << 16 | func);
		*pcidevfn = addr;
		*handle = dev_handle;
	} else {
		goto err;
	}

	if (!*handle)
		goto err;
	ret = 0;
err:
	kfree(dinfo);
	return ret;
}

struct walk_info {		/* can be trimmed some */
	struct device	*dev;
	struct acpi_device *adev;
	acpi_handle	handle;
	acpi_integer	pcidevfn;
	unsigned int	drivenum;
	acpi_handle	obj_handle;
	struct ata_port *ataport;
	struct ata_device *atadev;
	u32		sata_adr;
	int		status;
	char		basepath[ACPI_PATHNAME_MAX];
	int		basepath_len;
};

static acpi_status get_devices(acpi_handle handle,
				u32 level, void *context, void **return_value)
{
	acpi_status		status;
	struct walk_info	*winfo = context;
	struct acpi_buffer	namebuf = {ACPI_ALLOCATE_BUFFER, NULL};
	char			*pathname;
	struct acpi_buffer	buffer;
	struct acpi_device_info	*dinfo;

	status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf);
	if (status)
		goto ret;
	pathname = namebuf.pointer;

	buffer.length = ACPI_ALLOCATE_BUFFER;
	buffer.pointer = NULL;
	status = acpi_get_object_info(handle, &buffer);
	if (ACPI_FAILURE(status))
		goto out2;

	dinfo = buffer.pointer;

	/* find full device path name for pcidevfn */
	if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
	    dinfo->address == winfo->pcidevfn) {
		if (ata_msg_probe(winfo->ataport))
			ata_dev_printk(winfo->atadev, KERN_DEBUG,
				":%s: matches pcidevfn (0x%llx)\n",
				pathname, winfo->pcidevfn);
		strlcpy(winfo->basepath, pathname,
			sizeof(winfo->basepath));
		winfo->basepath_len = strlen(pathname);
		goto out;
	}

	/* if basepath is not yet known, ignore this object */
	if (!winfo->basepath_len)
		goto out;

	/* if this object is in scope of basepath, maybe use it */
	if (strncmp(pathname, winfo->basepath,
	    winfo->basepath_len) == 0) {
		if (!(dinfo->valid & ACPI_VALID_ADR))
			goto out;
		if (ata_msg_probe(winfo->ataport))
			ata_dev_printk(winfo->atadev, KERN_DEBUG,
				"GOT ONE: (%s) root_port = 0x%llx,"
				" port_num = 0x%llx\n", pathname,
				SATA_ROOT_PORT(dinfo->address),
				SATA_PORT_NUMBER(dinfo->address));
		/* heuristics: */
		if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
			if (ata_msg_probe(winfo->ataport))
				ata_dev_printk(winfo->atadev,
					KERN_DEBUG, "warning: don't"
					" know how to handle SATA port"
					" multiplier\n");
		if (SATA_ROOT_PORT(dinfo->address) ==
			winfo->ataport->port_no &&
		    SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
			if (ata_msg_probe(winfo->ataport))
				ata_dev_printk(winfo->atadev,
					KERN_DEBUG,
					"THIS ^^^^^ is the requested"
					" SATA drive (handle = 0x%p)\n",
					handle);
			winfo->sata_adr = dinfo->address;
			winfo->obj_handle = handle;
		}
	}
out:
	kfree(dinfo);
out2:
	kfree(pathname);

ret:
	return status;
}

/* Get the SATA drive _ADR object. */
static int get_sata_adr(struct device *dev, acpi_handle handle,
			acpi_integer pcidevfn, unsigned int drive,
			struct ata_port *ap,
			struct ata_device *atadev, u32 *dev_adr)
{
	acpi_status	status;
	struct walk_info *winfo;
	int		err = -ENOMEM;

	winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL);
	if (!winfo)
		goto out;

	winfo->dev = dev;
	winfo->atadev = atadev;
	winfo->ataport = ap;
	if (acpi_bus_get_device(handle, &winfo->adev) < 0)
		if (ata_msg_probe(ap))
			ata_dev_printk(winfo->atadev, KERN_DEBUG,
				"acpi_bus_get_device failed\n");
	winfo->handle = handle;
	winfo->pcidevfn = pcidevfn;
	winfo->drivenum = drive;

	status = acpi_get_devices(NULL, get_devices, winfo, NULL);
	if (ACPI_FAILURE(status)) {
		if (ata_msg_probe(ap))
			ata_dev_printk(winfo->atadev, KERN_DEBUG,
				"%s: acpi_get_devices failed\n",
				__FUNCTION__);
		err = -ENODEV;
	} else {
		*dev_adr = winfo->sata_adr;
		atadev->obj_handle = winfo->obj_handle;
		err = 0;
	}
	kfree(winfo);
out:
	return err;
}

/**
 * do_drive_get_GTF - get the drive bootup default taskfile settings
 * @ap: the ata_port for the drive
 * @ix: target ata_device (drive) index
 * @gtf_length: number of bytes of _GTF data returned at @gtf_address
 * @gtf_address: buffer containing _GTF taskfile arrays
 *
 * This applies to both PATA and SATA drives.
 *
 * The _GTF method has no input parameters.
 * It returns a variable number of register set values (registers
 * hex 1F1..1F7, taskfiles).
 * The <variable number> is not known in advance, so have ACPI-CA
 * allocate the buffer as needed and return it, then free it later.
 *
 * The returned @gtf_length and @gtf_address are only valid if the
 * function return value is 0.
 */
static int do_drive_get_GTF(struct ata_port *ap, int ix,
			unsigned int *gtf_length, unsigned long *gtf_address,
			unsigned long *obj_loc)
{
	acpi_status			status;
	acpi_handle			dev_handle = NULL;
	acpi_handle			chan_handle, drive_handle;
	acpi_integer			pcidevfn = 0;
	u32				dev_adr;
	struct acpi_buffer		output;
	union acpi_object 		*out_obj;
	struct device			*dev = ap->host->dev;
	struct ata_device		*atadev = &ap->device[ix];
	int				err = -ENODEV;

	*gtf_length = 0;
	*gtf_address = 0UL;
	*obj_loc = 0UL;

	if (libata_noacpi)
		return 0;

	if (ata_msg_probe(ap))
		ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
			       __FUNCTION__, ap->port_no);

	if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) {
		if (ata_msg_probe(ap))
			ata_dev_printk(atadev, KERN_DEBUG, "%s: ERR: "
				"ata_dev_present: %d, PORT_DISABLED: %lu\n",
				__FUNCTION__, ata_dev_enabled(atadev),
				ap->flags & ATA_FLAG_DISABLED);
		goto out;
	}

	/* Don't continue if device has no _ADR method.
	 * _GTF is intended for known motherboard devices. */
	if (!(ap->cbl == ATA_CBL_SATA)) {
		err = pata_get_dev_handle(dev, &dev_handle, &pcidevfn);
		if (err < 0) {
			if (ata_msg_probe(ap))
				ata_dev_printk(atadev, KERN_DEBUG,
					"%s: pata_get_dev_handle failed (%d)\n",
					__FUNCTION__, err);
			goto out;
		}
	} else {
		err = sata_get_dev_handle(dev, &dev_handle, &pcidevfn);
		if (err < 0) {
			if (ata_msg_probe(ap))
				ata_dev_printk(atadev, KERN_DEBUG,
					"%s: sata_get_dev_handle failed (%d\n",
					__FUNCTION__, err);
			goto out;
		}
	}

	/* Get this drive's _ADR info. if not already known. */
	if (!atadev->obj_handle) {
		if (!(ap->cbl == ATA_CBL_SATA)) {
			/* get child objects of dev_handle == channel objects,
	 		 * + _their_ children == drive objects */
			/* channel is ap->port_no */
			chan_handle = acpi_get_child(dev_handle,
						ap->port_no);
			if (ata_msg_probe(ap))
				ata_dev_printk(atadev, KERN_DEBUG,
					"%s: chan adr=%d: chan_handle=0x%p\n",
					__FUNCTION__, ap->port_no,
					chan_handle);
			if (!chan_handle) {
				err = -ENODEV;
				goto out;
			}
			/* TBD: could also check ACPI object VALID bits */
			drive_handle = acpi_get_child(chan_handle, ix);
			if (!drive_handle) {
				err = -ENODEV;
				goto out;
			}
			dev_adr = ix;
			atadev->obj_handle = drive_handle;
		} else {	/* for SATA mode */
			dev_adr = SATA_ADR_RSVD;
			err = get_sata_adr(dev, dev_handle, pcidevfn, 0,
					ap, atadev, &dev_adr);
		}
		if (err < 0 || dev_adr == SATA_ADR_RSVD ||
		    !atadev->obj_handle) {
			if (ata_msg_probe(ap))
				ata_dev_printk(atadev, KERN_DEBUG,
					"%s: get_sata/pata_adr failed: "
					"err=%d, dev_adr=%u, obj_handle=0x%p\n",
					__FUNCTION__, err, dev_adr,
					atadev->obj_handle);
			goto out;
		}
	}

	/* Setting up output buffer */
	output.length = ACPI_ALLOCATE_BUFFER;
	output.pointer = NULL;	/* ACPI-CA sets this; save/free it later */

	/* _GTF has no input parameters */
	err = -EIO;
	status = acpi_evaluate_object(atadev->obj_handle, "_GTF",
					NULL, &output);
	if (ACPI_FAILURE(status)) {
		if (ata_msg_probe(ap))
			ata_dev_printk(atadev, KERN_DEBUG,
				"%s: Run _GTF error: status = 0x%x\n",
				__FUNCTION__, status);
		goto out;
	}

	if (!output.length || !output.pointer) {
		if (ata_msg_probe(ap))
			ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
				"length or ptr is NULL (0x%llx, 0x%p)\n",
				__FUNCTION__,
				(unsigned long long)output.length,
				output.pointer);
		kfree(output.pointer);
		goto out;
	}

	out_obj = output.pointer;
	if (out_obj->type != ACPI_TYPE_BUFFER) {
		kfree(output.pointer);
		if (ata_msg_probe(ap))
			ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
				"error: expected object type of "
				" ACPI_TYPE_BUFFER, got 0x%x\n",
				__FUNCTION__, out_obj->type);
		err = -ENOENT;
		goto out;
	}

	if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
	    out_obj->buffer.length % REGS_PER_GTF) {
		if (ata_msg_drv(ap))
			ata_dev_printk(atadev, KERN_ERR,
				"%s: unexpected GTF length (%d) or addr (0x%p)\n",
				__FUNCTION__, out_obj->buffer.length,
				out_obj->buffer.pointer);
		err = -ENOENT;
		goto out;
	}

	*gtf_length = out_obj->buffer.length;
	*gtf_address = (unsigned long)out_obj->buffer.pointer;
	*obj_loc = (unsigned long)out_obj;
	if (ata_msg_probe(ap))
		ata_dev_printk(atadev, KERN_DEBUG, "%s: returning "
			"gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
			__FUNCTION__, *gtf_length, *gtf_address, *obj_loc);
	err = 0;
out:
	return err;
}

/**
 * taskfile_load_raw - send taskfile registers to host controller
 * @ap: Port to which output is sent
 * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
 *
 * Outputs ATA taskfile to standard ATA host controller using MMIO
 * or PIO as indicated by the ATA_FLAG_MMIO flag.
 * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
 * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
 * hob_lbal, hob_lbam, and hob_lbah.
 *
 * This function waits for idle (!BUSY and !DRQ) after writing
 * registers.  If the control register has a new value, this
 * function also waits for idle after writing control and before
 * writing the remaining registers.
 *
 * LOCKING: TBD:
 * Inherited from caller.
 */
static void taskfile_load_raw(struct ata_port *ap,
				struct ata_device *atadev,
				const struct taskfile_array *gtf)
{
	struct ata_taskfile tf;
	unsigned int err;

	if (ata_msg_probe(ap))
		ata_dev_printk(atadev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
			"%02x %02x %02x %02x %02x %02x %02x\n",
			__FUNCTION__,
			gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
			gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);

	if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0)
	    && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0)
	    && (gtf->tfa[6] == 0))
		return;

	ata_tf_init(atadev, &tf);

	/* convert gtf to tf */
	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
	tf.protocol = ATA_PROT_NODATA;
	tf.feature = gtf->tfa[0];	/* 0x1f1 */
	tf.nsect   = gtf->tfa[1];	/* 0x1f2 */
	tf.lbal    = gtf->tfa[2];	/* 0x1f3 */
	tf.lbam    = gtf->tfa[3];	/* 0x1f4 */
	tf.lbah    = gtf->tfa[4];	/* 0x1f5 */
	tf.device  = gtf->tfa[5];	/* 0x1f6 */
	tf.command = gtf->tfa[6];	/* 0x1f7 */

	err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0);
	if (err && ata_msg_probe(ap))
		ata_dev_printk(atadev, KERN_ERR,
			"%s: ata_exec_internal failed: %u\n",
			__FUNCTION__, err);
}

/**
 * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
 * @ap: the ata_port for the drive
 * @atadev: target ata_device
 * @gtf_length: total number of bytes of _GTF taskfiles
 * @gtf_address: location of _GTF taskfile arrays
 *
 * This applies to both PATA and SATA drives.
 *
 * Write {gtf_address, length gtf_length} in groups of
 * REGS_PER_GTF bytes.
 */
static int do_drive_set_taskfiles(struct ata_port *ap,
		struct ata_device *atadev, unsigned int gtf_length,
		unsigned long gtf_address)
{
	int			err = -ENODEV;
	int			gtf_count = gtf_length / REGS_PER_GTF;
	int			ix;
	struct taskfile_array	*gtf;

	if (ata_msg_probe(ap))
		ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
			       __FUNCTION__, ap->port_no);

	if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA))
		return 0;

	if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED))
		goto out;
	if (!gtf_count)		/* shouldn't be here */
		goto out;

	if (gtf_length % REGS_PER_GTF) {
		if (ata_msg_drv(ap))
			ata_dev_printk(atadev, KERN_ERR,
				"%s: unexpected GTF length (%d)\n",
				__FUNCTION__, gtf_length);
		goto out;
	}

	for (ix = 0; ix < gtf_count; ix++) {
		gtf = (struct taskfile_array *)
			(gtf_address + ix * REGS_PER_GTF);

		/* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
		taskfile_load_raw(ap, atadev, gtf);
	}

	err = 0;
out:
	return err;
}

/**
 * ata_acpi_exec_tfs - get then write drive taskfile settings
 * @ap: the ata_port for the drive
 *
 * This applies to both PATA and SATA drives.
 */
int ata_acpi_exec_tfs(struct ata_port *ap)
{
	int		ix;
	int		ret =0;
	unsigned int	gtf_length;
	unsigned long	gtf_address;
	unsigned long	obj_loc;

	if (libata_noacpi)
		return 0;
	/*
	 * TBD - implement PATA support.  For now,
	 * we should not run GTF on PATA devices since some
	 * PATA require execution of GTM/STM before GTF.
	 */
	if (!(ap->cbl == ATA_CBL_SATA))
		return 0;

	for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
		if (!ata_dev_enabled(&ap->device[ix]))
			continue;

		ret = do_drive_get_GTF(ap, ix,
				&gtf_length, &gtf_address, &obj_loc);
		if (ret < 0) {
			if (ata_msg_probe(ap))
				ata_port_printk(ap, KERN_DEBUG,
					"%s: get_GTF error (%d)\n",
					__FUNCTION__, ret);
			break;
		}

		ret = do_drive_set_taskfiles(ap, &ap->device[ix],
				gtf_length, gtf_address);
		kfree((void *)obj_loc);
		if (ret < 0) {
			if (ata_msg_probe(ap))
				ata_port_printk(ap, KERN_DEBUG,
					"%s: set_taskfiles error (%d)\n",
					__FUNCTION__, ret);
			break;
		}
	}

	return ret;
}

/**
 * ata_acpi_push_id - send Identify data to drive
 * @ap: the ata_port for the drive
 * @ix: drive index
 *
 * _SDD ACPI object: for SATA mode only
 * Must be after Identify (Packet) Device -- uses its data
 * ATM this function never returns a failure.  It is an optional
 * method and if it fails for whatever reason, we should still
 * just keep going.
 */
int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
{
	acpi_handle                     handle;
	acpi_integer                    pcidevfn;
	int                             err;
	struct device                   *dev = ap->host->dev;
	struct ata_device               *atadev = &ap->device[ix];
	u32                             dev_adr;
	acpi_status                     status;
	struct acpi_object_list         input;
	union acpi_object               in_params[1];

	if (libata_noacpi)
		return 0;

	if (ata_msg_probe(ap))
		ata_dev_printk(atadev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
			       __FUNCTION__, ix, ap->port_no);

	/* Don't continue if not a SATA device. */
	if (!(ap->cbl == ATA_CBL_SATA)) {
		if (ata_msg_probe(ap))
			ata_dev_printk(atadev, KERN_DEBUG,
				"%s: Not a SATA device\n", __FUNCTION__);
		goto out;
	}

	/* Don't continue if device has no _ADR method.
	 * _SDD is intended for known motherboard devices. */
	err = sata_get_dev_handle(dev, &handle, &pcidevfn);
	if (err < 0) {
		if (ata_msg_probe(ap))
			ata_dev_printk(atadev, KERN_DEBUG,
				"%s: sata_get_dev_handle failed (%d\n",
				__FUNCTION__, err);
		goto out;
	}

	/* Get this drive's _ADR info, if not already known */
	if (!atadev->obj_handle) {
		dev_adr = SATA_ADR_RSVD;
		err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev,
					&dev_adr);
		if (err < 0 || dev_adr == SATA_ADR_RSVD ||
			!atadev->obj_handle) {
			if (ata_msg_probe(ap))
				ata_dev_printk(atadev, KERN_DEBUG,
					"%s: get_sata_adr failed: "
					"err=%d, dev_adr=%u, obj_handle=0x%p\n",
					__FUNCTION__, err, dev_adr,
					atadev->obj_handle);
			goto out;
		}
	}

	/* Give the drive Identify data to the drive via the _SDD method */
	/* _SDD: set up input parameters */
	input.count = 1;
	input.pointer = in_params;
	in_params[0].type = ACPI_TYPE_BUFFER;
	in_params[0].buffer.length = sizeof(atadev->id[0]) * ATA_ID_WORDS;
	in_params[0].buffer.pointer = (u8 *)atadev->id;
	/* Output buffer: _SDD has no output */

	/* It's OK for _SDD to be missing too. */
	swap_buf_le16(atadev->id, ATA_ID_WORDS);
	status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
	swap_buf_le16(atadev->id, ATA_ID_WORDS);

	err = ACPI_FAILURE(status) ? -EIO : 0;
	if (err < 0) {
		if (ata_msg_probe(ap))
			ata_dev_printk(atadev, KERN_DEBUG,
				       "%s _SDD error: status = 0x%x\n",
				       __FUNCTION__, status);
	}

	/* always return success */
out:
	return 0;
}


