Commit fdb36f50 authored by Jeff Garzik's avatar Jeff Garzik

[libata] abstract SCSI->ATA translation a bit

parent 62e88cfd
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "libata.h" #include "libata.h"
typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd, struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *)); void (*done)(struct scsi_cmnd *));
...@@ -335,7 +336,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) ...@@ -335,7 +336,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd, struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *)) void (*done)(struct scsi_cmnd *),
ata_xlat_func_t xlat_func)
{ {
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
u8 *scsicmd = cmd->cmnd; u8 *scsicmd = cmd->cmnd;
...@@ -352,9 +354,11 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, ...@@ -352,9 +354,11 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
if (!qc) if (!qc)
return; return;
qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */ if (cmd->sc_data_direction == SCSI_DATA_READ ||
cmd->sc_data_direction == SCSI_DATA_WRITE)
qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */
if (ata_scsi_rw_xlat(qc, scsicmd)) if (xlat_func(qc, scsicmd))
goto err_out; goto err_out;
/* select device, send command to hardware */ /* select device, send command to hardware */
...@@ -1014,17 +1018,17 @@ ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd) ...@@ -1014,17 +1018,17 @@ ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
} }
/** /**
* ata_scsi_xlat_possible - check if SCSI to ATA translation is possible * ata_get_xlat_func - check if SCSI to ATA translation is possible
* @cmd: SCSI command opcode to consider * @cmd: SCSI command opcode to consider
* *
* Look up the SCSI command given, and determine whether the * Look up the SCSI command given, and determine whether the
* SCSI command is to be translated or simulated. * SCSI command is to be translated or simulated.
* *
* RETURNS: * RETURNS:
* Non-zero if possible, zero if not. * Pointer to translation function if possible, %NULL if not.
*/ */
static inline int ata_scsi_xlat_possible(u8 cmd) static inline ata_xlat_func_t ata_get_xlat_func(u8 cmd)
{ {
switch (cmd) { switch (cmd) {
case READ_6: case READ_6:
...@@ -1034,10 +1038,10 @@ static inline int ata_scsi_xlat_possible(u8 cmd) ...@@ -1034,10 +1038,10 @@ static inline int ata_scsi_xlat_possible(u8 cmd)
case WRITE_6: case WRITE_6:
case WRITE_10: case WRITE_10:
case WRITE_16: case WRITE_16:
return 1; return ata_scsi_rw_xlat;
} }
return 0; return NULL;
} }
/** /**
...@@ -1099,8 +1103,10 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) ...@@ -1099,8 +1103,10 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
} }
if (dev->class == ATA_DEV_ATA) { if (dev->class == ATA_DEV_ATA) {
if (ata_scsi_xlat_possible(cmd->cmnd[0])) ata_xlat_func_t xlat_func = ata_get_xlat_func(cmd->cmnd[0]);
ata_scsi_translate(ap, dev, cmd, done);
if (xlat_func)
ata_scsi_translate(ap, dev, cmd, done, xlat_func);
else else
ata_scsi_simulate(ap, dev, cmd, done); ata_scsi_simulate(ap, dev, cmd, done);
} else } else
......
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