diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-08-29 19:01:43 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-29 19:01:43 -0400 |
commit | da61396d24e37258817e42537c482e962b4742f7 (patch) | |
tree | 4293a5d557b8f9fed8a2bac93f1e5c939c7b65c3 /drivers/scsi/libata-scsi.c | |
parent | 2f058256cb64e346f4fb4499ff4e0f1c2791a4b4 (diff) | |
parent | 8f3d17fb7bcb7c255197d11469fb5e9695c9d2f4 (diff) |
Merge upstream kernel into libata 'passthru' branch
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 121 |
1 files changed, 100 insertions, 21 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 3ba1fefb8374..a980701d06c7 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -1,25 +1,36 @@ | |||
1 | /* | 1 | /* |
2 | libata-scsi.c - helper library for ATA | 2 | * libata-scsi.c - helper library for ATA |
3 | 3 | * | |
4 | Copyright 2003-2004 Red Hat, Inc. All rights reserved. | 4 | * Maintained by: Jeff Garzik <jgarzik@pobox.com> |
5 | Copyright 2003-2004 Jeff Garzik | 5 | * Please ALWAYS copy linux-ide@vger.kernel.org |
6 | 6 | * on emails. | |
7 | The contents of this file are subject to the Open | 7 | * |
8 | Software License version 1.1 that can be found at | 8 | * Copyright 2003-2004 Red Hat, Inc. All rights reserved. |
9 | http://www.opensource.org/licenses/osl-1.1.txt and is included herein | 9 | * Copyright 2003-2004 Jeff Garzik |
10 | by reference. | 10 | * |
11 | 11 | * | |
12 | Alternatively, the contents of this file may be used under the terms | 12 | * This program is free software; you can redistribute it and/or modify |
13 | of the GNU General Public License version 2 (the "GPL") as distributed | 13 | * it under the terms of the GNU General Public License as published by |
14 | in the kernel source COPYING file, in which case the provisions of | 14 | * the Free Software Foundation; either version 2, or (at your option) |
15 | the GPL are applicable instead of the above. If you wish to allow | 15 | * any later version. |
16 | the use of your version of this file only under the terms of the | 16 | * |
17 | GPL and not to allow others to use your version of this file under | 17 | * This program is distributed in the hope that it will be useful, |
18 | the OSL, indicate your decision by deleting the provisions above and | 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | replace them with the notice and other provisions required by the GPL. | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | If you do not delete the provisions above, a recipient may use your | 20 | * GNU General Public License for more details. |
21 | version of this file under either the OSL or the GPL. | 21 | * |
22 | 22 | * You should have received a copy of the GNU General Public License | |
23 | * along with this program; see the file COPYING. If not, write to | ||
24 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | * | ||
26 | * | ||
27 | * libata documentation is available via 'make {ps|pdf}docs', | ||
28 | * as Documentation/DocBook/libata.* | ||
29 | * | ||
30 | * Hardware documentation available from | ||
31 | * - http://www.t10.org/ | ||
32 | * - http://www.t13.org/ | ||
33 | * | ||
23 | */ | 34 | */ |
24 | 35 | ||
25 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
@@ -667,12 +678,67 @@ int ata_scsi_error(struct Scsi_Host *host) | |||
667 | * appropriate place | 678 | * appropriate place |
668 | */ | 679 | */ |
669 | host->host_failed--; | 680 | host->host_failed--; |
681 | INIT_LIST_HEAD(&host->eh_cmd_q); | ||
670 | 682 | ||
671 | DPRINTK("EXIT\n"); | 683 | DPRINTK("EXIT\n"); |
672 | return 0; | 684 | return 0; |
673 | } | 685 | } |
674 | 686 | ||
675 | /** | 687 | /** |
688 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command | ||
689 | * @qc: Storage for translated ATA taskfile | ||
690 | * @scsicmd: SCSI command to translate | ||
691 | * | ||
692 | * Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY | ||
693 | * (to start). Perhaps these commands should be preceded by | ||
694 | * CHECK POWER MODE to see what power mode the device is already in. | ||
695 | * [See SAT revision 5 at www.t10.org] | ||
696 | * | ||
697 | * LOCKING: | ||
698 | * spin_lock_irqsave(host_set lock) | ||
699 | * | ||
700 | * RETURNS: | ||
701 | * Zero on success, non-zero on error. | ||
702 | */ | ||
703 | |||
704 | static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, | ||
705 | u8 *scsicmd) | ||
706 | { | ||
707 | struct ata_taskfile *tf = &qc->tf; | ||
708 | |||
709 | tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | ||
710 | tf->protocol = ATA_PROT_NODATA; | ||
711 | if (scsicmd[1] & 0x1) { | ||
712 | ; /* ignore IMMED bit, violates sat-r05 */ | ||
713 | } | ||
714 | if (scsicmd[4] & 0x2) | ||
715 | return 1; /* LOEJ bit set not supported */ | ||
716 | if (((scsicmd[4] >> 4) & 0xf) != 0) | ||
717 | return 1; /* power conditions not supported */ | ||
718 | if (scsicmd[4] & 0x1) { | ||
719 | tf->nsect = 1; /* 1 sector, lba=0 */ | ||
720 | tf->lbah = 0x0; | ||
721 | tf->lbam = 0x0; | ||
722 | tf->lbal = 0x0; | ||
723 | tf->device |= ATA_LBA; | ||
724 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ | ||
725 | } else { | ||
726 | tf->nsect = 0; /* time period value (0 implies now) */ | ||
727 | tf->command = ATA_CMD_STANDBY; | ||
728 | /* Consider: ATA STANDBY IMMEDIATE command */ | ||
729 | } | ||
730 | /* | ||
731 | * Standby and Idle condition timers could be implemented but that | ||
732 | * would require libata to implement the Power condition mode page | ||
733 | * and allow the user to change it. Changing mode pages requires | ||
734 | * MODE SELECT to be implemented. | ||
735 | */ | ||
736 | |||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | |||
741 | /** | ||
676 | * ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command | 742 | * ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command |
677 | * @qc: Storage for translated ATA taskfile | 743 | * @qc: Storage for translated ATA taskfile |
678 | * @scsicmd: SCSI command to translate (ignored) | 744 | * @scsicmd: SCSI command to translate (ignored) |
@@ -857,11 +923,19 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
857 | tf->lbah = scsicmd[3]; | 923 | tf->lbah = scsicmd[3]; |
858 | 924 | ||
859 | VPRINTK("ten-byte command\n"); | 925 | VPRINTK("ten-byte command\n"); |
926 | if (qc->nsect == 0) /* we don't support length==0 cmds */ | ||
927 | return 1; | ||
860 | return 0; | 928 | return 0; |
861 | } | 929 | } |
862 | 930 | ||
863 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { | 931 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { |
864 | qc->nsect = tf->nsect = scsicmd[4]; | 932 | qc->nsect = tf->nsect = scsicmd[4]; |
933 | if (!qc->nsect) { | ||
934 | qc->nsect = 256; | ||
935 | if (lba48) | ||
936 | tf->hob_nsect = 1; | ||
937 | } | ||
938 | |||
865 | tf->lbal = scsicmd[3]; | 939 | tf->lbal = scsicmd[3]; |
866 | tf->lbam = scsicmd[2]; | 940 | tf->lbam = scsicmd[2]; |
867 | tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ | 941 | 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) | |||
901 | tf->lbah = scsicmd[7]; | 975 | tf->lbah = scsicmd[7]; |
902 | 976 | ||
903 | VPRINTK("sixteen-byte command\n"); | 977 | VPRINTK("sixteen-byte command\n"); |
978 | if (qc->nsect == 0) /* we don't support length==0 cmds */ | ||
979 | return 1; | ||
904 | return 0; | 980 | return 0; |
905 | } | 981 | } |
906 | 982 | ||
@@ -1881,6 +1957,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) | |||
1881 | case ATA_12: | 1957 | case ATA_12: |
1882 | case ATA_16: | 1958 | case ATA_16: |
1883 | return ata_scsi_pass_thru; | 1959 | return ata_scsi_pass_thru; |
1960 | |||
1961 | case START_STOP: | ||
1962 | return ata_scsi_start_stop_xlat; | ||
1884 | } | 1963 | } |
1885 | 1964 | ||
1886 | return NULL; | 1965 | return NULL; |