Merge upstream kernel into libata 'passthru' branch
This commit is contained in:
@ -1,25 +1,36 @@
|
||||
/*
|
||||
libata-scsi.c - helper library for ATA
|
||||
|
||||
Copyright 2003-2004 Red Hat, Inc. All rights reserved.
|
||||
Copyright 2003-2004 Jeff Garzik
|
||||
|
||||
The contents of this file are subject to the Open
|
||||
Software License version 1.1 that can be found at
|
||||
http://www.opensource.org/licenses/osl-1.1.txt and is included herein
|
||||
by reference.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms
|
||||
of the GNU General Public License version 2 (the "GPL") as distributed
|
||||
in the kernel source COPYING file, in which case the provisions of
|
||||
the GPL are applicable instead of the above. If you wish to allow
|
||||
the use of your version of this file only under the terms of the
|
||||
GPL and not to allow others to use your version of this file under
|
||||
the OSL, indicate your decision by deleting the provisions above and
|
||||
replace them with the notice and other provisions required by the GPL.
|
||||
If you do not delete the provisions above, a recipient may use your
|
||||
version of this file under either the OSL or the GPL.
|
||||
|
||||
* libata-scsi.c - helper library for ATA
|
||||
*
|
||||
* Maintained by: Jeff Garzik <jgarzik@pobox.com>
|
||||
* Please ALWAYS copy linux-ide@vger.kernel.org
|
||||
* on emails.
|
||||
*
|
||||
* Copyright 2003-2004 Red Hat, Inc. All rights reserved.
|
||||
* Copyright 2003-2004 Jeff Garzik
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* libata documentation is available via 'make {ps|pdf}docs',
|
||||
* as Documentation/DocBook/libata.*
|
||||
*
|
||||
* Hardware documentation available from
|
||||
* - http://www.t10.org/
|
||||
* - http://www.t13.org/
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@ -667,11 +678,66 @@ int ata_scsi_error(struct Scsi_Host *host)
|
||||
* appropriate place
|
||||
*/
|
||||
host->host_failed--;
|
||||
INIT_LIST_HEAD(&host->eh_cmd_q);
|
||||
|
||||
DPRINTK("EXIT\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
|
||||
* @qc: Storage for translated ATA taskfile
|
||||
* @scsicmd: SCSI command to translate
|
||||
*
|
||||
* Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY
|
||||
* (to start). Perhaps these commands should be preceded by
|
||||
* CHECK POWER MODE to see what power mode the device is already in.
|
||||
* [See SAT revision 5 at www.t10.org]
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, non-zero on error.
|
||||
*/
|
||||
|
||||
static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
|
||||
u8 *scsicmd)
|
||||
{
|
||||
struct ata_taskfile *tf = &qc->tf;
|
||||
|
||||
tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
|
||||
tf->protocol = ATA_PROT_NODATA;
|
||||
if (scsicmd[1] & 0x1) {
|
||||
; /* ignore IMMED bit, violates sat-r05 */
|
||||
}
|
||||
if (scsicmd[4] & 0x2)
|
||||
return 1; /* LOEJ bit set not supported */
|
||||
if (((scsicmd[4] >> 4) & 0xf) != 0)
|
||||
return 1; /* power conditions not supported */
|
||||
if (scsicmd[4] & 0x1) {
|
||||
tf->nsect = 1; /* 1 sector, lba=0 */
|
||||
tf->lbah = 0x0;
|
||||
tf->lbam = 0x0;
|
||||
tf->lbal = 0x0;
|
||||
tf->device |= ATA_LBA;
|
||||
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
|
||||
} else {
|
||||
tf->nsect = 0; /* time period value (0 implies now) */
|
||||
tf->command = ATA_CMD_STANDBY;
|
||||
/* Consider: ATA STANDBY IMMEDIATE command */
|
||||
}
|
||||
/*
|
||||
* Standby and Idle condition timers could be implemented but that
|
||||
* would require libata to implement the Power condition mode page
|
||||
* and allow the user to change it. Changing mode pages requires
|
||||
* MODE SELECT to be implemented.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
|
||||
* @qc: Storage for translated ATA taskfile
|
||||
@ -857,11 +923,19 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
|
||||
tf->lbah = scsicmd[3];
|
||||
|
||||
VPRINTK("ten-byte command\n");
|
||||
if (qc->nsect == 0) /* we don't support length==0 cmds */
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
|
||||
qc->nsect = tf->nsect = scsicmd[4];
|
||||
if (!qc->nsect) {
|
||||
qc->nsect = 256;
|
||||
if (lba48)
|
||||
tf->hob_nsect = 1;
|
||||
}
|
||||
|
||||
tf->lbal = scsicmd[3];
|
||||
tf->lbam = scsicmd[2];
|
||||
tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */
|
||||
@ -901,6 +975,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
|
||||
tf->lbah = scsicmd[7];
|
||||
|
||||
VPRINTK("sixteen-byte command\n");
|
||||
if (qc->nsect == 0) /* we don't support length==0 cmds */
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1881,6 +1957,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
|
||||
case ATA_12:
|
||||
case ATA_16:
|
||||
return ata_scsi_pass_thru;
|
||||
|
||||
case START_STOP:
|
||||
return ata_scsi_start_stop_xlat;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
Reference in New Issue
Block a user