#include "libata.h"
-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
+typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
static struct ata_device *
-ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev);
+ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
*/
static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
- u8 *scsicmd)
+ const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
tf->flags |= ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- if ((tf->flags & ATA_TFLAG_LBA48) &&
+ if ((qc->dev->flags & ATA_DFLAG_LBA48) &&
(ata_id_has_flush_ext(qc->dev->id)))
tf->command = ATA_CMD_FLUSH_EXT;
else
* @plen: the transfer length
*/
-static void scsi_6_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
* @plen: the transfer length
*/
-static void scsi_10_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
* @plen: the transfer length
*/
-static void scsi_16_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
- unsigned int lba = tf->flags & ATA_TFLAG_LBA;
- unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
u64 dev_sectors = qc->dev->n_sectors;
u64 block;
u32 n_block;
goto out_of_range;
if ((block + n_block) > dev_sectors)
goto out_of_range;
- if (lba48) {
- if (n_block > (64 * 1024))
- goto invalid_fld;
- } else {
- if (n_block > 256)
- goto invalid_fld;
- }
- if (lba) {
- if (lba48) {
+ if (dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
+
+ if (dev->flags & ATA_DFLAG_LBA48) {
+ if (n_block > (64 * 1024))
+ goto invalid_fld;
+
+ /* use LBA48 */
+ tf->flags |= ATA_TFLAG_LBA48;
tf->command = ATA_CMD_VERIFY_EXT;
tf->hob_nsect = (n_block >> 8) & 0xff;
tf->hob_lbam = (block >> 32) & 0xff;
tf->hob_lbal = (block >> 24) & 0xff;
} else {
+ if (n_block > 256)
+ goto invalid_fld;
+
+ /* use LBA28 */
tf->command = ATA_CMD_VERIFY;
tf->device |= (block >> 24) & 0xf;
/* CHS */
u32 sect, head, cyl, track;
+ if (n_block > 256)
+ goto invalid_fld;
+
/* Convert LBA to CHS */
track = (u32)block / dev->sectors;
cyl = track / dev->heads;
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
- unsigned int lba = tf->flags & ATA_TFLAG_LBA;
- unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
u64 block;
u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- tf->protocol = qc->dev->xfer_protocol;
- if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
- scsicmd[0] == READ_16) {
- tf->command = qc->dev->read_cmd;
- } else {
- tf->command = qc->dev->write_cmd;
+ if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
+ scsicmd[0] == WRITE_16)
tf->flags |= ATA_TFLAG_WRITE;
- }
/* Calculate the SCSI LBA and transfer length. */
switch (scsicmd[0]) {
*/
goto nothing_to_do;
- if (lba) {
- if (lba48) {
+ if (dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
+
+ if (dev->flags & ATA_DFLAG_LBA48) {
/* The request -may- be too large for LBA48. */
if ((block >> 48) || (n_block > 65536))
goto out_of_range;
+ /* use LBA48 */
+ tf->flags |= ATA_TFLAG_LBA48;
+
tf->hob_nsect = (n_block >> 8) & 0xff;
tf->hob_lbah = (block >> 40) & 0xff;
tf->hob_lbam = (block >> 32) & 0xff;
tf->hob_lbal = (block >> 24) & 0xff;
} else {
- /* LBA28 */
+ /* use LBA28 */
/* The request -may- be too large for LBA28. */
if ((block >> 28) || (n_block > 256))
tf->device |= (block >> 24) & 0xf;
}
+ ata_rwcmd_protocol(qc);
+
qc->nsect = n_block;
tf->nsect = n_block & 0xff;
if ((block >> 28) || (n_block > 256))
goto out_of_range;
+ ata_rwcmd_protocol(qc);
+
/* Convert LBA to CHS */
track = (u32)block / dev->sectors;
cyl = track / dev->heads;
* Zero on success, non-zero on failure.
*/
-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
*/
static struct ata_device *
-ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev)
+ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
{
struct ata_device *dev;
void (*done)(struct scsi_cmnd *))
{
struct ata_scsi_args args;
- u8 *scsicmd = cmd->cmnd;
+ const u8 *scsicmd = cmd->cmnd;
args.id = id;
args.cmd = cmd;