diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-08-29 19:24:43 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-29 19:24:43 -0400 |
commit | 76b2bf9b4dee2fb32ef17f5c84a99ce481a14be2 (patch) | |
tree | 49cd36d6e980044c2a88f2c14cdc9259e0f0f1b4 /drivers/scsi/libata-scsi.c | |
parent | 2fca877b68b2b4fc5b94277858a1bedd46017cde (diff) | |
parent | 8f3d17fb7bcb7c255197d11469fb5e9695c9d2f4 (diff) |
Merge libata branch 'chs-support' to latest upstream kernel.
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 112 |
1 files changed, 91 insertions, 21 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 954d1bca3b2a..f8ddc2a29e9a 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -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> @@ -392,6 +403,60 @@ int ata_scsi_error(struct Scsi_Host *host) } /** + * 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 * @scsicmd: SCSI command to translate (ignored) @@ -598,7 +663,10 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) } else if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { block |= ((u64)scsicmd[2]) << 8; block |= ((u64)scsicmd[3]); + n_block |= ((u32)scsicmd[4]); + if (!n_block) + n_block = 256; VPRINTK("six-byte command\n"); } else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { @@ -1509,6 +1577,8 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) case VERIFY: case VERIFY_16: return ata_scsi_verify_xlat; + case START_STOP: + return ata_scsi_start_stop_xlat; } return NULL; |