}
/**
- * 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
* 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;
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;
}
return err_mask;
}
+/**
+ * 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
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);