From 2432697ba0ce312d60be5009ffe1fa054a761bb9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Nov 2006 22:47:09 +0900 Subject: [PATCH] [PATCH] libata: implement ata_exec_internal_sg() Sg'ify ata_exec_internal() and call it ata_exec_internal_sg(). Wrapper function around ata_exec_internal_sg() is implemented to provide ata_exec_internal() interface. Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 49 ++++++++++++++++++++++++++++++++++++++++------- drivers/ata/libata.h | 4 ++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 47c70392ec4..0a5103b707c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1042,13 +1042,13 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc) } /** - * ata_exec_internal - execute libata internal command + * ata_exec_internal_sg - execute libata internal command * @dev: Device to which the command is sent * @tf: Taskfile registers for the command and the result * @cdb: CDB for packet command * @dma_dir: Data tranfer direction of the command - * @buf: Data buffer of the command - * @buflen: Length of data buffer + * @sg: sg list for the data buffer of the command + * @n_elem: Number of sg entries * * Executes libata internal command with timeout. @tf contains * command on entry and result on return. Timeout and error @@ -1062,9 +1062,10 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc) * RETURNS: * Zero on success, AC_ERR_* mask on failure */ -unsigned ata_exec_internal(struct ata_device *dev, - struct ata_taskfile *tf, const u8 *cdb, - int dma_dir, void *buf, unsigned int buflen) +unsigned ata_exec_internal_sg(struct ata_device *dev, + struct ata_taskfile *tf, const u8 *cdb, + int dma_dir, struct scatterlist *sg, + unsigned int n_elem) { struct ata_port *ap = dev->ap; u8 command = tf->command; @@ -1120,7 +1121,12 @@ unsigned ata_exec_internal(struct ata_device *dev, qc->flags |= ATA_QCFLAG_RESULT_TF; qc->dma_dir = dma_dir; if (dma_dir != DMA_NONE) { - ata_sg_init_one(qc, buf, buflen); + unsigned int i, buflen = 0; + + for (i = 0; i < n_elem; i++) + buflen += sg[i].length; + + ata_sg_init(qc, sg, n_elem); qc->nsect = buflen / ATA_SECT_SIZE; } @@ -1204,6 +1210,35 @@ unsigned ata_exec_internal(struct ata_device *dev, } /** + * ata_exec_internal_sg - execute libata internal command + * @dev: Device to which the command is sent + * @tf: Taskfile registers for the command and the result + * @cdb: CDB for packet command + * @dma_dir: Data tranfer direction of the command + * @buf: Data buffer of the command + * @buflen: Length of data buffer + * + * Wrapper around ata_exec_internal_sg() which takes simple + * buffer instead of sg list. + * + * LOCKING: + * None. Should be called with kernel context, might sleep. + * + * RETURNS: + * Zero on success, AC_ERR_* mask on failure + */ +unsigned ata_exec_internal(struct ata_device *dev, + struct ata_taskfile *tf, const u8 *cdb, + int dma_dir, void *buf, unsigned int buflen) +{ + struct scatterlist sg; + + sg_init_one(&sg, buf, buflen); + + return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1); +} + +/** * ata_do_simple_cmd - execute simple internal command * @dev: Device to which the command is sent * @cmd: Opcode to execute diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 2d532da8c39..ca6f36c1311 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -58,6 +58,10 @@ extern void ata_port_flush_task(struct ata_port *ap); extern unsigned ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf, const u8 *cdb, int dma_dir, void *buf, unsigned int buflen); +extern unsigned ata_exec_internal_sg(struct ata_device *dev, + struct ata_taskfile *tf, const u8 *cdb, + int dma_dir, struct scatterlist *sg, + unsigned int n_elem); extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, unsigned int flags, u16 *id); -- 2.11.4.GIT