| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 |  | 
|  | 2 | /* | 
| Jeff Garzik | af36d7f | 2005-08-28 20:18:39 -0400 | [diff] [blame] | 3 | *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved. | 
|  | 4 | *  Copyright 2003-2004 Jeff Garzik | 
|  | 5 | * | 
|  | 6 | * | 
|  | 7 | *  This program is free software; you can redistribute it and/or modify | 
|  | 8 | *  it under the terms of the GNU General Public License as published by | 
|  | 9 | *  the Free Software Foundation; either version 2, or (at your option) | 
|  | 10 | *  any later version. | 
|  | 11 | * | 
|  | 12 | *  This program is distributed in the hope that it will be useful, | 
|  | 13 | *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 14 | *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 15 | *  GNU General Public License for more details. | 
|  | 16 | * | 
|  | 17 | *  You should have received a copy of the GNU General Public License | 
|  | 18 | *  along with this program; see the file COPYING.  If not, write to | 
|  | 19 | *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 
|  | 20 | * | 
|  | 21 | * | 
|  | 22 | *  libata documentation is available via 'make {ps|pdf}docs', | 
|  | 23 | *  as Documentation/DocBook/libata.* | 
|  | 24 | * | 
|  | 25 | *  Hardware documentation available from http://www.t13.org/ | 
|  | 26 | * | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 27 | */ | 
|  | 28 |  | 
|  | 29 | #ifndef __LINUX_ATA_H__ | 
|  | 30 | #define __LINUX_ATA_H__ | 
|  | 31 |  | 
|  | 32 | #include <linux/types.h> | 
|  | 33 |  | 
|  | 34 | /* defines only for the constants which don't work well as enums */ | 
|  | 35 | #define ATA_DMA_BOUNDARY	0xffffUL | 
|  | 36 | #define ATA_DMA_MASK		0xffffffffULL | 
|  | 37 |  | 
|  | 38 | enum { | 
|  | 39 | /* various global constants */ | 
|  | 40 | ATA_MAX_DEVICES		= 2,	/* per bus/port */ | 
|  | 41 | ATA_MAX_PRD		= 256,	/* we could make these 256/256 */ | 
|  | 42 | ATA_SECT_SIZE		= 512, | 
| Albert Lee | 18d6e9d | 2007-04-02 11:34:15 +0800 | [diff] [blame] | 43 | ATA_MAX_SECTORS_128	= 128, | 
| Jeff Garzik | 8b881b0 | 2006-06-11 09:59:27 -0400 | [diff] [blame] | 44 | ATA_MAX_SECTORS		= 256, | 
|  | 45 | ATA_MAX_SECTORS_LBA48	= 65535,/* TODO: 65536? */ | 
| Tony Battersby | f8d8e57 | 2007-10-30 11:44:35 -0400 | [diff] [blame] | 46 | ATA_MAX_SECTORS_TAPE	= 65535, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 47 |  | 
|  | 48 | ATA_ID_WORDS		= 256, | 
| Tejun Heo | a0cf733 | 2007-01-02 20:18:49 +0900 | [diff] [blame] | 49 | ATA_ID_SERNO		= 10, | 
|  | 50 | ATA_ID_FW_REV		= 23, | 
|  | 51 | ATA_ID_PROD		= 27, | 
| Alan Cox | 11e29e2 | 2005-10-21 18:46:32 -0400 | [diff] [blame] | 52 | ATA_ID_OLD_PIO_MODES	= 51, | 
|  | 53 | ATA_ID_FIELD_VALID	= 53, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 54 | ATA_ID_MWDMA_MODES	= 63, | 
| Alan Cox | 11e29e2 | 2005-10-21 18:46:32 -0400 | [diff] [blame] | 55 | ATA_ID_PIO_MODES	= 64, | 
|  | 56 | ATA_ID_EIDE_DMA_MIN	= 65, | 
|  | 57 | ATA_ID_EIDE_PIO		= 67, | 
|  | 58 | ATA_ID_EIDE_PIO_IORDY	= 68, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 59 | ATA_ID_UDMA_MODES	= 88, | 
| Alan Cox | 11e29e2 | 2005-10-21 18:46:32 -0400 | [diff] [blame] | 60 | ATA_ID_MAJOR_VER	= 80, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 61 | ATA_ID_PIO4		= (1 << 1), | 
|  | 62 |  | 
| Tejun Heo | a0cf733 | 2007-01-02 20:18:49 +0900 | [diff] [blame] | 63 | ATA_ID_SERNO_LEN	= 20, | 
|  | 64 | ATA_ID_FW_REV_LEN	= 8, | 
|  | 65 | ATA_ID_PROD_LEN		= 40, | 
|  | 66 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | ATA_PCI_CTL_OFS		= 2, | 
| Bartlomiej Zolnierkiewicz | 4099d14 | 2007-07-20 01:11:59 +0200 | [diff] [blame] | 68 |  | 
|  | 69 | ATA_PIO0		= (1 << 0), | 
|  | 70 | ATA_PIO1		= ATA_PIO0 | (1 << 1), | 
|  | 71 | ATA_PIO2		= ATA_PIO1 | (1 << 2), | 
|  | 72 | ATA_PIO3		= ATA_PIO2 | (1 << 3), | 
|  | 73 | ATA_PIO4		= ATA_PIO3 | (1 << 4), | 
|  | 74 | ATA_PIO5		= ATA_PIO4 | (1 << 5), | 
|  | 75 | ATA_PIO6		= ATA_PIO5 | (1 << 6), | 
|  | 76 |  | 
| Bartlomiej Zolnierkiewicz | 91a6d4e | 2007-08-27 19:35:22 +0200 | [diff] [blame] | 77 | ATA_SWDMA0		= (1 << 0), | 
|  | 78 | ATA_SWDMA1		= ATA_SWDMA0 | (1 << 1), | 
|  | 79 | ATA_SWDMA2		= ATA_SWDMA1 | (1 << 2), | 
|  | 80 |  | 
|  | 81 | ATA_SWDMA2_ONLY		= (1 << 2), | 
|  | 82 |  | 
|  | 83 | ATA_MWDMA0		= (1 << 0), | 
|  | 84 | ATA_MWDMA1		= ATA_MWDMA0 | (1 << 1), | 
|  | 85 | ATA_MWDMA2		= ATA_MWDMA1 | (1 << 2), | 
|  | 86 |  | 
|  | 87 | ATA_MWDMA12_ONLY	= (1 << 1) | (1 << 2), | 
|  | 88 | ATA_MWDMA2_ONLY		= (1 << 2), | 
|  | 89 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 90 | ATA_UDMA0		= (1 << 0), | 
|  | 91 | ATA_UDMA1		= ATA_UDMA0 | (1 << 1), | 
|  | 92 | ATA_UDMA2		= ATA_UDMA1 | (1 << 2), | 
|  | 93 | ATA_UDMA3		= ATA_UDMA2 | (1 << 3), | 
|  | 94 | ATA_UDMA4		= ATA_UDMA3 | (1 << 4), | 
|  | 95 | ATA_UDMA5		= ATA_UDMA4 | (1 << 5), | 
|  | 96 | ATA_UDMA6		= ATA_UDMA5 | (1 << 6), | 
|  | 97 | ATA_UDMA7		= ATA_UDMA6 | (1 << 7), | 
|  | 98 | /* ATA_UDMA7 is just for completeness... doesn't exist (yet?).  */ | 
|  | 99 |  | 
|  | 100 | ATA_UDMA_MASK_40C	= ATA_UDMA2,	/* udma0-2 */ | 
|  | 101 |  | 
|  | 102 | /* DMA-related */ | 
|  | 103 | ATA_PRD_SZ		= 8, | 
|  | 104 | ATA_PRD_TBL_SZ		= (ATA_MAX_PRD * ATA_PRD_SZ), | 
|  | 105 | ATA_PRD_EOT		= (1 << 31),	/* end-of-table flag */ | 
|  | 106 |  | 
|  | 107 | ATA_DMA_TABLE_OFS	= 4, | 
|  | 108 | ATA_DMA_STATUS		= 2, | 
|  | 109 | ATA_DMA_CMD		= 0, | 
|  | 110 | ATA_DMA_WR		= (1 << 3), | 
|  | 111 | ATA_DMA_START		= (1 << 0), | 
|  | 112 | ATA_DMA_INTR		= (1 << 2), | 
|  | 113 | ATA_DMA_ERR		= (1 << 1), | 
|  | 114 | ATA_DMA_ACTIVE		= (1 << 0), | 
|  | 115 |  | 
|  | 116 | /* bits in ATA command block registers */ | 
|  | 117 | ATA_HOB			= (1 << 7),	/* LBA48 selector */ | 
|  | 118 | ATA_NIEN		= (1 << 1),	/* disable-irq flag */ | 
|  | 119 | ATA_LBA			= (1 << 6),	/* LBA28 selector */ | 
|  | 120 | ATA_DEV1		= (1 << 4),	/* Select Device 1 (slave) */ | 
|  | 121 | ATA_DEVICE_OBS		= (1 << 7) | (1 << 5), /* obs bits in dev reg */ | 
|  | 122 | ATA_DEVCTL_OBS		= (1 << 3),	/* obsolete bit in devctl reg */ | 
|  | 123 | ATA_BUSY		= (1 << 7),	/* BSY status bit */ | 
|  | 124 | ATA_DRDY		= (1 << 6),	/* device ready */ | 
|  | 125 | ATA_DF			= (1 << 5),	/* device fault */ | 
|  | 126 | ATA_DRQ			= (1 << 3),	/* data request i/o */ | 
|  | 127 | ATA_ERR			= (1 << 0),	/* have an error */ | 
|  | 128 | ATA_SRST		= (1 << 2),	/* software reset */ | 
| Tejun Heo | 9be1e97 | 2006-05-15 20:58:17 +0900 | [diff] [blame] | 129 | ATA_ICRC		= (1 << 7),	/* interface CRC error */ | 
|  | 130 | ATA_UNC			= (1 << 6),	/* uncorrectable media error */ | 
|  | 131 | ATA_IDNF		= (1 << 4),	/* ID not found */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 132 | ATA_ABORTED		= (1 << 2),	/* command aborted */ | 
|  | 133 |  | 
|  | 134 | /* ATA command block registers */ | 
|  | 135 | ATA_REG_DATA		= 0x00, | 
|  | 136 | ATA_REG_ERR		= 0x01, | 
|  | 137 | ATA_REG_NSECT		= 0x02, | 
|  | 138 | ATA_REG_LBAL		= 0x03, | 
|  | 139 | ATA_REG_LBAM		= 0x04, | 
|  | 140 | ATA_REG_LBAH		= 0x05, | 
|  | 141 | ATA_REG_DEVICE		= 0x06, | 
|  | 142 | ATA_REG_STATUS		= 0x07, | 
|  | 143 |  | 
|  | 144 | ATA_REG_FEATURE		= ATA_REG_ERR, /* and their aliases */ | 
|  | 145 | ATA_REG_CMD		= ATA_REG_STATUS, | 
|  | 146 | ATA_REG_BYTEL		= ATA_REG_LBAM, | 
|  | 147 | ATA_REG_BYTEH		= ATA_REG_LBAH, | 
|  | 148 | ATA_REG_DEVSEL		= ATA_REG_DEVICE, | 
|  | 149 | ATA_REG_IRQ		= ATA_REG_NSECT, | 
|  | 150 |  | 
|  | 151 | /* ATA device commands */ | 
| Jeff Garzik | ab2181c | 2007-05-28 08:30:36 -0400 | [diff] [blame] | 152 | ATA_CMD_DEV_RESET	= 0x08, /* ATAPI device reset */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 153 | ATA_CMD_CHK_POWER	= 0xE5, /* check power mode */ | 
| Douglas Gilbert | 972dcaf | 2005-08-11 03:35:53 -0400 | [diff] [blame] | 154 | ATA_CMD_STANDBY		= 0xE2, /* place in standby power mode */ | 
|  | 155 | ATA_CMD_IDLE		= 0xE3, /* place in idle power mode */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 156 | ATA_CMD_EDD		= 0x90,	/* execute device diagnostic */ | 
|  | 157 | ATA_CMD_FLUSH		= 0xE7, | 
|  | 158 | ATA_CMD_FLUSH_EXT	= 0xEA, | 
|  | 159 | ATA_CMD_ID_ATA		= 0xEC, | 
|  | 160 | ATA_CMD_ID_ATAPI	= 0xA1, | 
|  | 161 | ATA_CMD_READ		= 0xC8, | 
|  | 162 | ATA_CMD_READ_EXT	= 0x25, | 
|  | 163 | ATA_CMD_WRITE		= 0xCA, | 
|  | 164 | ATA_CMD_WRITE_EXT	= 0x35, | 
| Tejun Heo | 9a3dccc | 2006-01-06 09:56:18 +0100 | [diff] [blame] | 165 | ATA_CMD_WRITE_FUA_EXT	= 0x3D, | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 166 | ATA_CMD_FPDMA_READ	= 0x60, | 
|  | 167 | ATA_CMD_FPDMA_WRITE	= 0x61, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 168 | ATA_CMD_PIO_READ	= 0x20, | 
|  | 169 | ATA_CMD_PIO_READ_EXT	= 0x24, | 
|  | 170 | ATA_CMD_PIO_WRITE	= 0x30, | 
|  | 171 | ATA_CMD_PIO_WRITE_EXT	= 0x34, | 
| Albert Lee | 8cbd6df | 2005-10-12 15:06:27 +0800 | [diff] [blame] | 172 | ATA_CMD_READ_MULTI	= 0xC4, | 
|  | 173 | ATA_CMD_READ_MULTI_EXT	= 0x29, | 
|  | 174 | ATA_CMD_WRITE_MULTI	= 0xC5, | 
|  | 175 | ATA_CMD_WRITE_MULTI_EXT	= 0x39, | 
| Tejun Heo | 9a3dccc | 2006-01-06 09:56:18 +0100 | [diff] [blame] | 176 | ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 177 | ATA_CMD_SET_FEATURES	= 0xEF, | 
| Albert Lee | 2c3d2a4 | 2007-06-07 16:01:17 +0800 | [diff] [blame] | 178 | ATA_CMD_SET_MULTI	= 0xC6, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 179 | ATA_CMD_PACKET		= 0xA0, | 
|  | 180 | ATA_CMD_VERIFY		= 0x40, | 
|  | 181 | ATA_CMD_VERIFY_EXT	= 0x42, | 
| Jeff Garzik | 2dcb407 | 2007-10-19 06:42:56 -0400 | [diff] [blame] | 182 | ATA_CMD_STANDBYNOW1	= 0xE0, | 
|  | 183 | ATA_CMD_IDLEIMMEDIATE	= 0xE1, | 
| Tejun Heo | 054a5fb | 2007-10-25 18:30:36 +0900 | [diff] [blame] | 184 | ATA_CMD_SLEEP		= 0xE6, | 
| Albert Lee | 8bf62ec | 2005-05-12 15:29:42 -0400 | [diff] [blame] | 185 | ATA_CMD_INIT_DEV_PARAMS	= 0x91, | 
| Alan Cox | b678272 | 2006-03-21 15:52:49 +0000 | [diff] [blame] | 186 | ATA_CMD_READ_NATIVE_MAX	= 0xF8, | 
|  | 187 | ATA_CMD_READ_NATIVE_MAX_EXT = 0x27, | 
| Alan Cox | 1e99973 | 2007-04-11 00:23:13 +0100 | [diff] [blame] | 188 | ATA_CMD_SET_MAX		= 0xF9, | 
|  | 189 | ATA_CMD_SET_MAX_EXT	= 0x37, | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 190 | ATA_CMD_READ_LOG_EXT	= 0x2f, | 
| Tejun Heo | 814600e | 2007-07-01 19:05:58 +0900 | [diff] [blame] | 191 | ATA_CMD_PMP_READ	= 0xE4, | 
|  | 192 | ATA_CMD_PMP_WRITE	= 0xE8, | 
| Tejun Heo | ce2e0ab | 2007-12-15 15:04:59 +0900 | [diff] [blame] | 193 | ATA_CMD_CONF_OVERLAY	= 0xB1, | 
|  | 194 | ATA_CMD_SEC_FREEZE_LOCK	= 0xF5, | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 195 |  | 
|  | 196 | /* READ_LOG_EXT pages */ | 
|  | 197 | ATA_LOG_SATA_NCQ	= 0x10, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 198 |  | 
| Mark Lord | 5a5dbd1 | 2007-03-16 10:22:26 -0400 | [diff] [blame] | 199 | /* READ/WRITE LONG (obsolete) */ | 
|  | 200 | ATA_CMD_READ_LONG	= 0x22, | 
|  | 201 | ATA_CMD_READ_LONG_ONCE	= 0x23, | 
|  | 202 | ATA_CMD_WRITE_LONG	= 0x32, | 
|  | 203 | ATA_CMD_WRITE_LONG_ONCE	= 0x33, | 
|  | 204 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 205 | /* SETFEATURES stuff */ | 
|  | 206 | SETFEATURES_XFER	= 0x03, | 
|  | 207 | XFER_UDMA_7		= 0x47, | 
|  | 208 | XFER_UDMA_6		= 0x46, | 
|  | 209 | XFER_UDMA_5		= 0x45, | 
|  | 210 | XFER_UDMA_4		= 0x44, | 
|  | 211 | XFER_UDMA_3		= 0x43, | 
|  | 212 | XFER_UDMA_2		= 0x42, | 
|  | 213 | XFER_UDMA_1		= 0x41, | 
|  | 214 | XFER_UDMA_0		= 0x40, | 
| Alan Cox | b352e57 | 2006-08-10 18:52:12 +0100 | [diff] [blame] | 215 | XFER_MW_DMA_4		= 0x24,	/* CFA only */ | 
|  | 216 | XFER_MW_DMA_3		= 0x23,	/* CFA only */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 217 | XFER_MW_DMA_2		= 0x22, | 
|  | 218 | XFER_MW_DMA_1		= 0x21, | 
|  | 219 | XFER_MW_DMA_0		= 0x20, | 
| Alan Cox | b4b52db | 2005-09-26 12:48:41 +0100 | [diff] [blame] | 220 | XFER_SW_DMA_2		= 0x12, | 
|  | 221 | XFER_SW_DMA_1		= 0x11, | 
|  | 222 | XFER_SW_DMA_0		= 0x10, | 
| Alan Cox | b352e57 | 2006-08-10 18:52:12 +0100 | [diff] [blame] | 223 | XFER_PIO_6		= 0x0E,	/* CFA only */ | 
|  | 224 | XFER_PIO_5		= 0x0D,	/* CFA only */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 225 | XFER_PIO_4		= 0x0C, | 
|  | 226 | XFER_PIO_3		= 0x0B, | 
|  | 227 | XFER_PIO_2		= 0x0A, | 
|  | 228 | XFER_PIO_1		= 0x09, | 
|  | 229 | XFER_PIO_0		= 0x08, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 230 | XFER_PIO_SLOW		= 0x00, | 
|  | 231 |  | 
| zhao, forrest | 3057ac3 | 2006-06-12 12:01:34 +0800 | [diff] [blame] | 232 | SETFEATURES_WC_ON	= 0x02, /* Enable write cache */ | 
|  | 233 | SETFEATURES_WC_OFF	= 0x82, /* Disable write cache */ | 
|  | 234 |  | 
| Mark Lord | 169439c | 2007-04-17 18:26:07 -0400 | [diff] [blame] | 235 | SETFEATURES_SPINUP	= 0x07, /* Spin-up drive */ | 
|  | 236 |  | 
| Kristen Carlson Accardi | 9f45cbd | 2007-08-15 03:57:11 -0400 | [diff] [blame] | 237 | SETFEATURES_SATA_ENABLE = 0x10, /* Enable use of SATA feature */ | 
|  | 238 | SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */ | 
|  | 239 |  | 
|  | 240 | /* SETFEATURE Sector counts for SATA features */ | 
|  | 241 | SATA_AN			= 0x05,  /* Asynchronous Notification */ | 
| Kristen Carlson Accardi | ca77329 | 2007-10-25 00:58:59 -0400 | [diff] [blame] | 242 | SATA_DIPM		= 0x03,  /* Device Initiated Power Management */ | 
| Kristen Carlson Accardi | 9f45cbd | 2007-08-15 03:57:11 -0400 | [diff] [blame] | 243 |  | 
| Tejun Heo | ce2e0ab | 2007-12-15 15:04:59 +0900 | [diff] [blame] | 244 | /* feature values for SET_MAX */ | 
|  | 245 | ATA_SET_MAX_ADDR	= 0x00, | 
|  | 246 | ATA_SET_MAX_PASSWD	= 0x01, | 
|  | 247 | ATA_SET_MAX_LOCK	= 0x02, | 
|  | 248 | ATA_SET_MAX_UNLOCK	= 0x03, | 
|  | 249 | ATA_SET_MAX_FREEZE_LOCK	= 0x04, | 
|  | 250 |  | 
|  | 251 | /* feature values for DEVICE CONFIGURATION OVERLAY */ | 
|  | 252 | ATA_DCO_RESTORE		= 0xC0, | 
|  | 253 | ATA_DCO_FREEZE_LOCK	= 0xC1, | 
|  | 254 | ATA_DCO_IDENTIFY	= 0xC2, | 
|  | 255 | ATA_DCO_SET		= 0xC3, | 
|  | 256 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 257 | /* ATAPI stuff */ | 
|  | 258 | ATAPI_PKT_DMA		= (1 << 0), | 
|  | 259 | ATAPI_DMADIR		= (1 << 2),	/* ATAPI data dir: | 
|  | 260 | 0=to device, 1=to host */ | 
|  | 261 | ATAPI_CDB_LEN		= 16, | 
|  | 262 |  | 
| Tejun Heo | 814600e | 2007-07-01 19:05:58 +0900 | [diff] [blame] | 263 | /* PMP stuff */ | 
|  | 264 | SATA_PMP_MAX_PORTS	= 15, | 
|  | 265 | SATA_PMP_CTRL_PORT	= 15, | 
|  | 266 |  | 
|  | 267 | SATA_PMP_GSCR_DWORDS	= 128, | 
|  | 268 | SATA_PMP_GSCR_PROD_ID	= 0, | 
|  | 269 | SATA_PMP_GSCR_REV	= 1, | 
|  | 270 | SATA_PMP_GSCR_PORT_INFO	= 2, | 
|  | 271 | SATA_PMP_GSCR_ERROR	= 32, | 
|  | 272 | SATA_PMP_GSCR_ERROR_EN	= 33, | 
|  | 273 | SATA_PMP_GSCR_FEAT	= 64, | 
|  | 274 | SATA_PMP_GSCR_FEAT_EN	= 96, | 
|  | 275 |  | 
|  | 276 | SATA_PMP_PSCR_STATUS	= 0, | 
|  | 277 | SATA_PMP_PSCR_ERROR	= 1, | 
|  | 278 | SATA_PMP_PSCR_CONTROL	= 2, | 
|  | 279 |  | 
|  | 280 | SATA_PMP_FEAT_BIST	= (1 << 0), | 
|  | 281 | SATA_PMP_FEAT_PMREQ	= (1 << 1), | 
|  | 282 | SATA_PMP_FEAT_DYNSSC	= (1 << 2), | 
|  | 283 | SATA_PMP_FEAT_NOTIFY	= (1 << 3), | 
|  | 284 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 285 | /* cable types */ | 
|  | 286 | ATA_CBL_NONE		= 0, | 
|  | 287 | ATA_CBL_PATA40		= 1, | 
|  | 288 | ATA_CBL_PATA80		= 2, | 
| Tejun Heo | c88f90c | 2007-11-27 19:43:48 +0900 | [diff] [blame] | 289 | ATA_CBL_PATA40_SHORT	= 3,	/* 40 wire cable to high UDMA spec */ | 
|  | 290 | ATA_CBL_PATA_UNK	= 4,	/* don't know, maybe 80c? */ | 
|  | 291 | ATA_CBL_PATA_IGN	= 5,	/* don't know, ignore cable handling */ | 
|  | 292 | ATA_CBL_SATA		= 6, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 293 |  | 
|  | 294 | /* SATA Status and Control Registers */ | 
|  | 295 | SCR_STATUS		= 0, | 
|  | 296 | SCR_ERROR		= 1, | 
|  | 297 | SCR_CONTROL		= 2, | 
|  | 298 | SCR_ACTIVE		= 3, | 
|  | 299 | SCR_NOTIFICATION	= 4, | 
|  | 300 |  | 
| Tejun Heo | 9be1e97 | 2006-05-15 20:58:17 +0900 | [diff] [blame] | 301 | /* SError bits */ | 
|  | 302 | SERR_DATA_RECOVERED	= (1 << 0), /* recovered data error */ | 
|  | 303 | SERR_COMM_RECOVERED	= (1 << 1), /* recovered comm failure */ | 
|  | 304 | SERR_DATA		= (1 << 8), /* unrecovered data error */ | 
|  | 305 | SERR_PERSISTENT		= (1 << 9), /* persistent data/comm error */ | 
|  | 306 | SERR_PROTOCOL		= (1 << 10), /* protocol violation */ | 
|  | 307 | SERR_INTERNAL		= (1 << 11), /* host internal error */ | 
|  | 308 | SERR_PHYRDY_CHG		= (1 << 16), /* PHY RDY changed */ | 
| Robert Hancock | 1333e19 | 2007-10-02 11:22:02 -0400 | [diff] [blame] | 309 | SERR_PHY_INT_ERR	= (1 << 17), /* PHY internal error */ | 
|  | 310 | SERR_COMM_WAKE		= (1 << 18), /* Comm wake */ | 
|  | 311 | SERR_10B_8B_ERR		= (1 << 19), /* 10b to 8b decode error */ | 
|  | 312 | SERR_DISPARITY		= (1 << 20), /* Disparity */ | 
|  | 313 | SERR_CRC		= (1 << 21), /* CRC error */ | 
|  | 314 | SERR_HANDSHAKE		= (1 << 22), /* Handshake error */ | 
|  | 315 | SERR_LINK_SEQ_ERR	= (1 << 23), /* Link sequence error */ | 
|  | 316 | SERR_TRANS_ST_ERROR	= (1 << 24), /* Transport state trans. error */ | 
|  | 317 | SERR_UNRECOG_FIS	= (1 << 25), /* Unrecognized FIS */ | 
| Tejun Heo | 9be1e97 | 2006-05-15 20:58:17 +0900 | [diff] [blame] | 318 | SERR_DEV_XCHG		= (1 << 26), /* device exchanged */ | 
|  | 319 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 320 | /* struct ata_taskfile flags */ | 
|  | 321 | ATA_TFLAG_LBA48		= (1 << 0), /* enable 48-bit LBA and "HOB" */ | 
|  | 322 | ATA_TFLAG_ISADDR	= (1 << 1), /* enable r/w to nsect/lba regs */ | 
|  | 323 | ATA_TFLAG_DEVICE	= (1 << 2), /* enable r/w to device reg */ | 
|  | 324 | ATA_TFLAG_WRITE		= (1 << 3), /* data dir: host->dev==1 (write) */ | 
| Albert Lee | 8bf62ec | 2005-05-12 15:29:42 -0400 | [diff] [blame] | 325 | ATA_TFLAG_LBA		= (1 << 4), /* enable LBA */ | 
| Tejun Heo | 9a3dccc | 2006-01-06 09:56:18 +0100 | [diff] [blame] | 326 | ATA_TFLAG_FUA		= (1 << 5), /* enable FUA */ | 
| Jeff Garzik | ea9b395 | 2006-01-17 10:29:06 -0500 | [diff] [blame] | 327 | ATA_TFLAG_POLLING	= (1 << 6), /* set nIEN to 1 and use polling */ | 
| Tejun Heo | 405e66b | 2007-11-27 19:28:53 +0900 | [diff] [blame] | 328 |  | 
|  | 329 | /* protocol flags */ | 
|  | 330 | ATA_PROT_FLAG_PIO	= (1 << 0), /* is PIO */ | 
|  | 331 | ATA_PROT_FLAG_DMA	= (1 << 1), /* is DMA */ | 
|  | 332 | ATA_PROT_FLAG_DATA	= ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA, | 
|  | 333 | ATA_PROT_FLAG_NCQ	= (1 << 2), /* is NCQ */ | 
|  | 334 | ATA_PROT_FLAG_ATAPI	= (1 << 3), /* is ATAPI */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 335 | }; | 
|  | 336 |  | 
|  | 337 | enum ata_tf_protocols { | 
|  | 338 | /* ATA taskfile protocols */ | 
|  | 339 | ATA_PROT_UNKNOWN,	/* unknown/invalid */ | 
|  | 340 | ATA_PROT_NODATA,	/* no data */ | 
| Albert Lee | 1dce589 | 2007-06-07 15:49:22 +0800 | [diff] [blame] | 341 | ATA_PROT_PIO,		/* PIO data xfer */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 342 | ATA_PROT_DMA,		/* DMA */ | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 343 | ATA_PROT_NCQ,		/* NCQ */ | 
| Tejun Heo | 0dc3688 | 2007-12-18 16:34:43 -0500 | [diff] [blame] | 344 | ATAPI_PROT_NODATA,	/* packet command, no data */ | 
|  | 345 | ATAPI_PROT_PIO,		/* packet command, PIO data xfer*/ | 
|  | 346 | ATAPI_PROT_DMA,		/* packet command with special DMA sauce */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 347 | }; | 
|  | 348 |  | 
|  | 349 | enum ata_ioctls { | 
|  | 350 | ATA_IOC_GET_IO32	= 0x309, | 
|  | 351 | ATA_IOC_SET_IO32	= 0x324, | 
|  | 352 | }; | 
|  | 353 |  | 
|  | 354 | /* core structures */ | 
|  | 355 |  | 
|  | 356 | struct ata_prd { | 
| Al Viro | 4ca4e43 | 2007-12-30 09:32:22 +0000 | [diff] [blame] | 357 | __le32			addr; | 
|  | 358 | __le32			flags_len; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 359 | }; | 
|  | 360 |  | 
|  | 361 | struct ata_taskfile { | 
|  | 362 | unsigned long		flags;		/* ATA_TFLAG_xxx */ | 
|  | 363 | u8			protocol;	/* ATA_PROT_xxx */ | 
|  | 364 |  | 
|  | 365 | u8			ctl;		/* control reg */ | 
|  | 366 |  | 
|  | 367 | u8			hob_feature;	/* additional data */ | 
|  | 368 | u8			hob_nsect;	/* to support LBA48 */ | 
|  | 369 | u8			hob_lbal; | 
|  | 370 | u8			hob_lbam; | 
|  | 371 | u8			hob_lbah; | 
|  | 372 |  | 
|  | 373 | u8			feature; | 
|  | 374 | u8			nsect; | 
|  | 375 | u8			lbal; | 
|  | 376 | u8			lbam; | 
|  | 377 | u8			lbah; | 
|  | 378 |  | 
|  | 379 | u8			device; | 
|  | 380 |  | 
|  | 381 | u8			command;	/* IO operation */ | 
|  | 382 | }; | 
|  | 383 |  | 
| Tejun Heo | 405e66b | 2007-11-27 19:28:53 +0900 | [diff] [blame] | 384 | /* | 
|  | 385 | * protocol tests | 
|  | 386 | */ | 
|  | 387 | static inline unsigned int ata_prot_flags(u8 prot) | 
|  | 388 | { | 
|  | 389 | switch (prot) { | 
|  | 390 | case ATA_PROT_NODATA: | 
|  | 391 | return 0; | 
|  | 392 | case ATA_PROT_PIO: | 
|  | 393 | return ATA_PROT_FLAG_PIO; | 
|  | 394 | case ATA_PROT_DMA: | 
|  | 395 | return ATA_PROT_FLAG_DMA; | 
|  | 396 | case ATA_PROT_NCQ: | 
|  | 397 | return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ; | 
| Tejun Heo | 0dc3688 | 2007-12-18 16:34:43 -0500 | [diff] [blame] | 398 | case ATAPI_PROT_NODATA: | 
| Tejun Heo | 405e66b | 2007-11-27 19:28:53 +0900 | [diff] [blame] | 399 | return ATA_PROT_FLAG_ATAPI; | 
| Tejun Heo | 0dc3688 | 2007-12-18 16:34:43 -0500 | [diff] [blame] | 400 | case ATAPI_PROT_PIO: | 
| Tejun Heo | 405e66b | 2007-11-27 19:28:53 +0900 | [diff] [blame] | 401 | return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO; | 
| Tejun Heo | 0dc3688 | 2007-12-18 16:34:43 -0500 | [diff] [blame] | 402 | case ATAPI_PROT_DMA: | 
| Tejun Heo | 405e66b | 2007-11-27 19:28:53 +0900 | [diff] [blame] | 403 | return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA; | 
|  | 404 | } | 
|  | 405 | return 0; | 
|  | 406 | } | 
|  | 407 |  | 
|  | 408 | static inline int ata_is_atapi(u8 prot) | 
|  | 409 | { | 
|  | 410 | return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI; | 
|  | 411 | } | 
|  | 412 |  | 
|  | 413 | static inline int ata_is_nodata(u8 prot) | 
|  | 414 | { | 
|  | 415 | return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA); | 
|  | 416 | } | 
|  | 417 |  | 
|  | 418 | static inline int ata_is_pio(u8 prot) | 
|  | 419 | { | 
|  | 420 | return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO; | 
|  | 421 | } | 
|  | 422 |  | 
|  | 423 | static inline int ata_is_dma(u8 prot) | 
|  | 424 | { | 
|  | 425 | return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA; | 
|  | 426 | } | 
|  | 427 |  | 
|  | 428 | static inline int ata_is_ncq(u8 prot) | 
|  | 429 | { | 
|  | 430 | return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ; | 
|  | 431 | } | 
|  | 432 |  | 
|  | 433 | static inline int ata_is_data(u8 prot) | 
|  | 434 | { | 
|  | 435 | return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA; | 
|  | 436 | } | 
|  | 437 |  | 
|  | 438 | /* | 
|  | 439 | * id tests | 
|  | 440 | */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 441 | #define ata_id_is_ata(id)	(((id)[0] & (1 << 15)) == 0) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 442 | #define ata_id_has_lba(id)	((id)[49] & (1 << 9)) | 
|  | 443 | #define ata_id_has_dma(id)	((id)[49] & (1 << 8)) | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 444 | #define ata_id_has_ncq(id)	((id)[76] & (1 << 8)) | 
|  | 445 | #define ata_id_queue_depth(id)	(((id)[75] & 0x1f) + 1) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 446 | #define ata_id_removeable(id)	((id)[0] & (1 << 7)) | 
| Tejun Heo | 854c73a | 2007-09-23 13:14:11 +0900 | [diff] [blame] | 447 | #define ata_id_has_atapi_AN(id)	\ | 
| Kristen Carlson Accardi | 9f45cbd | 2007-08-15 03:57:11 -0400 | [diff] [blame] | 448 | ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \ | 
|  | 449 | ((id)[78] & (1 << 5)) ) | 
| Alan | 49554c1 | 2007-02-05 16:17:19 +0000 | [diff] [blame] | 450 | #define ata_id_iordy_disable(id) ((id)[49] & (1 << 10)) | 
| Alan Cox | 0bc2a79 | 2007-07-31 14:01:48 +0100 | [diff] [blame] | 451 | #define ata_id_has_iordy(id) ((id)[49] & (1 << 11)) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 452 | #define ata_id_u32(id,n)	\ | 
|  | 453 | (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)])) | 
|  | 454 | #define ata_id_u64(id,n)	\ | 
|  | 455 | ( ((u64) (id)[(n) + 3] << 48) |	\ | 
|  | 456 | ((u64) (id)[(n) + 2] << 32) |	\ | 
|  | 457 | ((u64) (id)[(n) + 1] << 16) |	\ | 
|  | 458 | ((u64) (id)[(n) + 0]) ) | 
|  | 459 |  | 
| Albert Lee | 312f7da | 2005-09-27 17:38:03 +0800 | [diff] [blame] | 460 | #define ata_id_cdb_intr(id)	(((id)[0] & 0x60) == 0x20) | 
|  | 461 |  | 
| Kristen Carlson Accardi | ca77329 | 2007-10-25 00:58:59 -0400 | [diff] [blame] | 462 | static inline bool ata_id_has_hipm(const u16 *id) | 
|  | 463 | { | 
|  | 464 | u16 val = id[76]; | 
|  | 465 |  | 
|  | 466 | if (val == 0 || val == 0xffff) | 
|  | 467 | return false; | 
|  | 468 |  | 
|  | 469 | return val & (1 << 9); | 
|  | 470 | } | 
|  | 471 |  | 
|  | 472 | static inline bool ata_id_has_dipm(const u16 *id) | 
|  | 473 | { | 
|  | 474 | u16 val = id[78]; | 
|  | 475 |  | 
|  | 476 | if (val == 0 || val == 0xffff) | 
|  | 477 | return false; | 
|  | 478 |  | 
|  | 479 | return val & (1 << 3); | 
|  | 480 | } | 
|  | 481 |  | 
| Alan Cox | ae8d4ee | 2007-11-04 22:05:49 -0500 | [diff] [blame] | 482 |  | 
| Alan Cox | c729387 | 2007-08-22 23:31:43 +0100 | [diff] [blame] | 483 | static inline int ata_id_has_fua(const u16 *id) | 
|  | 484 | { | 
|  | 485 | if ((id[84] & 0xC000) != 0x4000) | 
|  | 486 | return 0; | 
|  | 487 | return id[84] & (1 << 6); | 
|  | 488 | } | 
|  | 489 |  | 
|  | 490 | static inline int ata_id_has_flush(const u16 *id) | 
|  | 491 | { | 
|  | 492 | if ((id[83] & 0xC000) != 0x4000) | 
|  | 493 | return 0; | 
|  | 494 | return id[83] & (1 << 12); | 
|  | 495 | } | 
|  | 496 |  | 
|  | 497 | static inline int ata_id_has_flush_ext(const u16 *id) | 
|  | 498 | { | 
|  | 499 | if ((id[83] & 0xC000) != 0x4000) | 
|  | 500 | return 0; | 
|  | 501 | return id[83] & (1 << 13); | 
|  | 502 | } | 
|  | 503 |  | 
|  | 504 | static inline int ata_id_has_lba48(const u16 *id) | 
|  | 505 | { | 
|  | 506 | if ((id[83] & 0xC000) != 0x4000) | 
|  | 507 | return 0; | 
| Geert Uytterhoeven | 17bd9a2 | 2007-10-29 21:21:37 +0100 | [diff] [blame] | 508 | if (!ata_id_u64(id, 100)) | 
|  | 509 | return 0; | 
| Alan Cox | c729387 | 2007-08-22 23:31:43 +0100 | [diff] [blame] | 510 | return id[83] & (1 << 10); | 
|  | 511 | } | 
|  | 512 |  | 
|  | 513 | static inline int ata_id_hpa_enabled(const u16 *id) | 
|  | 514 | { | 
|  | 515 | /* Yes children, word 83 valid bits cover word 82 data */ | 
|  | 516 | if ((id[83] & 0xC000) != 0x4000) | 
|  | 517 | return 0; | 
|  | 518 | /* And 87 covers 85-87 */ | 
|  | 519 | if ((id[87] & 0xC000) != 0x4000) | 
|  | 520 | return 0; | 
|  | 521 | /* Check command sets enabled as well as supported */ | 
|  | 522 | if ((id[85] & ( 1 << 10)) == 0) | 
|  | 523 | return 0; | 
|  | 524 | return id[82] & (1 << 10); | 
|  | 525 | } | 
|  | 526 |  | 
|  | 527 | static inline int ata_id_has_wcache(const u16 *id) | 
|  | 528 | { | 
|  | 529 | /* Yes children, word 83 valid bits cover word 82 data */ | 
|  | 530 | if ((id[83] & 0xC000) != 0x4000) | 
|  | 531 | return 0; | 
|  | 532 | return id[82] & (1 << 5); | 
|  | 533 | } | 
|  | 534 |  | 
|  | 535 | static inline int ata_id_has_pm(const u16 *id) | 
|  | 536 | { | 
|  | 537 | if ((id[83] & 0xC000) != 0x4000) | 
|  | 538 | return 0; | 
|  | 539 | return id[82] & (1 << 3); | 
|  | 540 | } | 
|  | 541 |  | 
|  | 542 | static inline int ata_id_rahead_enabled(const u16 *id) | 
|  | 543 | { | 
|  | 544 | if ((id[87] & 0xC000) != 0x4000) | 
|  | 545 | return 0; | 
|  | 546 | return id[85] & (1 << 6); | 
|  | 547 | } | 
|  | 548 |  | 
|  | 549 | static inline int ata_id_wcache_enabled(const u16 *id) | 
|  | 550 | { | 
|  | 551 | if ((id[87] & 0xC000) != 0x4000) | 
|  | 552 | return 0; | 
|  | 553 | return id[85] & (1 << 5); | 
|  | 554 | } | 
|  | 555 |  | 
|  | 556 | /** | 
|  | 557 | *	ata_id_major_version	-	get ATA level of drive | 
|  | 558 | *	@id: Identify data | 
|  | 559 | * | 
|  | 560 | *	Caveats: | 
|  | 561 | *		ATA-1 considers identify optional | 
|  | 562 | *		ATA-2 introduces mandatory identify | 
|  | 563 | *		ATA-3 introduces word 80 and accurate reporting | 
|  | 564 | * | 
|  | 565 | *	The practical impact of this is that ata_id_major_version cannot | 
| Jeff Garzik | 2dcb407 | 2007-10-19 06:42:56 -0400 | [diff] [blame] | 566 | *	reliably report on drives below ATA3. | 
| Alan Cox | c729387 | 2007-08-22 23:31:43 +0100 | [diff] [blame] | 567 | */ | 
|  | 568 |  | 
| Tejun Heo | 3d2ca91 | 2006-02-12 22:47:04 +0900 | [diff] [blame] | 569 | static inline unsigned int ata_id_major_version(const u16 *id) | 
|  | 570 | { | 
|  | 571 | unsigned int mver; | 
|  | 572 |  | 
| Alan Cox | b352e57 | 2006-08-10 18:52:12 +0100 | [diff] [blame] | 573 | if (id[ATA_ID_MAJOR_VER] == 0xFFFF) | 
|  | 574 | return 0; | 
|  | 575 |  | 
| Tejun Heo | 3d2ca91 | 2006-02-12 22:47:04 +0900 | [diff] [blame] | 576 | for (mver = 14; mver >= 1; mver--) | 
|  | 577 | if (id[ATA_ID_MAJOR_VER] & (1 << mver)) | 
|  | 578 | break; | 
|  | 579 | return mver; | 
|  | 580 | } | 
|  | 581 |  | 
| Tejun Heo | 32d9091 | 2007-02-21 20:25:08 +0900 | [diff] [blame] | 582 | static inline int ata_id_is_sata(const u16 *id) | 
|  | 583 | { | 
|  | 584 | return ata_id_major_version(id) >= 5 && id[93] == 0; | 
|  | 585 | } | 
|  | 586 |  | 
| Alan Cox | ae8d4ee | 2007-11-04 22:05:49 -0500 | [diff] [blame] | 587 | static inline int ata_id_has_tpm(const u16 *id) | 
|  | 588 | { | 
|  | 589 | /* The TPM bits are only valid on ATA8 */ | 
|  | 590 | if (ata_id_major_version(id) < 8) | 
|  | 591 | return 0; | 
|  | 592 | if ((id[48] & 0xC000) != 0x4000) | 
|  | 593 | return 0; | 
|  | 594 | return id[48] & (1 << 0); | 
|  | 595 | } | 
|  | 596 |  | 
|  | 597 | static inline int ata_id_has_dword_io(const u16 *id) | 
|  | 598 | { | 
|  | 599 | /* ATA 8 reuses this flag for "trusted" computing */ | 
|  | 600 | if (ata_id_major_version(id) > 7) | 
|  | 601 | return 0; | 
|  | 602 | if (id[48] & (1 << 0)) | 
|  | 603 | return 1; | 
|  | 604 | return 0; | 
|  | 605 | } | 
|  | 606 |  | 
| Jeff Garzik | 057ace5 | 2005-10-22 14:27:05 -0400 | [diff] [blame] | 607 | static inline int ata_id_current_chs_valid(const u16 *id) | 
| Albert Lee | 8bf62ec | 2005-05-12 15:29:42 -0400 | [diff] [blame] | 608 | { | 
| Jeff Garzik | 9bec2e3 | 2006-08-31 00:02:15 -0400 | [diff] [blame] | 609 | /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command | 
|  | 610 | has not been issued to the device then the values of | 
| Albert Lee | 8bf62ec | 2005-05-12 15:29:42 -0400 | [diff] [blame] | 611 | id[54] to id[56] are vendor specific. */ | 
|  | 612 | return (id[53] & 0x01) && /* Current translation valid */ | 
|  | 613 | id[54] &&  /* cylinders in current translation */ | 
|  | 614 | id[55] &&  /* heads in current translation */ | 
|  | 615 | id[55] <= 16 && | 
|  | 616 | id[56];    /* sectors in current translation */ | 
|  | 617 | } | 
|  | 618 |  | 
| Alan Cox | b352e57 | 2006-08-10 18:52:12 +0100 | [diff] [blame] | 619 | static inline int ata_id_is_cfa(const u16 *id) | 
|  | 620 | { | 
|  | 621 | u16 v = id[0]; | 
|  | 622 | if (v == 0x848A)	/* Standard CF */ | 
|  | 623 | return 1; | 
|  | 624 | /* Could be CF hiding as standard ATA */ | 
|  | 625 | if (ata_id_major_version(id) >= 3 &&  id[82] != 0xFFFF && | 
|  | 626 | (id[82] & ( 1 << 2))) | 
|  | 627 | return 1; | 
|  | 628 | return 0; | 
|  | 629 | } | 
|  | 630 |  | 
| Alan Cox | fc08515 | 2006-10-10 14:28:11 -0700 | [diff] [blame] | 631 | static inline int ata_drive_40wire(const u16 *dev_id) | 
|  | 632 | { | 
| Tejun Heo | 32d9091 | 2007-02-21 20:25:08 +0900 | [diff] [blame] | 633 | if (ata_id_is_sata(dev_id)) | 
| Alan Cox | fc08515 | 2006-10-10 14:28:11 -0700 | [diff] [blame] | 634 | return 0;	/* SATA */ | 
| Tejun Heo | 61f216c | 2007-02-05 23:21:19 +0900 | [diff] [blame] | 635 | if ((dev_id[93] & 0xE000) == 0x6000) | 
| Alan Cox | fc08515 | 2006-10-10 14:28:11 -0700 | [diff] [blame] | 636 | return 0;	/* 80 wire */ | 
|  | 637 | return 1; | 
|  | 638 | } | 
|  | 639 |  | 
| Alan Cox | 6bbfd53 | 2007-11-05 22:58:58 +0000 | [diff] [blame] | 640 | static inline int ata_drive_40wire_relaxed(const u16 *dev_id) | 
|  | 641 | { | 
| Alan Cox | 6bbfd53 | 2007-11-05 22:58:58 +0000 | [diff] [blame] | 642 | if ((dev_id[93] & 0x2000) == 0x2000) | 
|  | 643 | return 0;	/* 80 wire */ | 
|  | 644 | return 1; | 
|  | 645 | } | 
|  | 646 |  | 
| Jeff Garzik | 057ace5 | 2005-10-22 14:27:05 -0400 | [diff] [blame] | 647 | static inline int atapi_cdb_len(const u16 *dev_id) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 648 | { | 
|  | 649 | u16 tmp = dev_id[0] & 0x3; | 
|  | 650 | switch (tmp) { | 
|  | 651 | case 0:		return 12; | 
|  | 652 | case 1:		return 16; | 
|  | 653 | default:	return -1; | 
|  | 654 | } | 
|  | 655 | } | 
|  | 656 |  | 
| Tony Battersby | f8d8e57 | 2007-10-30 11:44:35 -0400 | [diff] [blame] | 657 | static inline int atapi_command_packet_set(const u16 *dev_id) | 
|  | 658 | { | 
|  | 659 | return (dev_id[0] >> 8) & 0x1f; | 
|  | 660 | } | 
|  | 661 |  | 
| Tejun Heo | 9116300 | 2008-02-21 13:25:50 +0900 | [diff] [blame] | 662 | static inline int atapi_id_dmadir(const u16 *dev_id) | 
|  | 663 | { | 
|  | 664 | return ata_id_major_version(dev_id) >= 7 && (dev_id[62] & 0x8000); | 
|  | 665 | } | 
|  | 666 |  | 
| Albert Lee | 07f6f7d | 2005-11-01 19:33:20 +0800 | [diff] [blame] | 667 | static inline int is_multi_taskfile(struct ata_taskfile *tf) | 
|  | 668 | { | 
|  | 669 | return (tf->command == ATA_CMD_READ_MULTI) || | 
|  | 670 | (tf->command == ATA_CMD_WRITE_MULTI) || | 
|  | 671 | (tf->command == ATA_CMD_READ_MULTI_EXT) || | 
| Albert Lee | c2956a3 | 2006-03-03 10:34:05 +0800 | [diff] [blame] | 672 | (tf->command == ATA_CMD_WRITE_MULTI_EXT) || | 
|  | 673 | (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT); | 
| Albert Lee | 07f6f7d | 2005-11-01 19:33:20 +0800 | [diff] [blame] | 674 | } | 
|  | 675 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 676 | static inline int ata_ok(u8 status) | 
|  | 677 | { | 
|  | 678 | return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR)) | 
|  | 679 | == ATA_DRDY); | 
|  | 680 | } | 
|  | 681 |  | 
| Albert Lee | c6a33e2 | 2005-10-12 15:12:26 +0800 | [diff] [blame] | 682 | static inline int lba_28_ok(u64 block, u32 n_block) | 
|  | 683 | { | 
|  | 684 | /* check the ending block number */ | 
|  | 685 | return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256); | 
|  | 686 | } | 
|  | 687 |  | 
|  | 688 | static inline int lba_48_ok(u64 block, u32 n_block) | 
|  | 689 | { | 
|  | 690 | /* check the ending block number */ | 
|  | 691 | return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536); | 
|  | 692 | } | 
|  | 693 |  | 
| Tejun Heo | 814600e | 2007-07-01 19:05:58 +0900 | [diff] [blame] | 694 | #define sata_pmp_gscr_vendor(gscr)	((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff) | 
|  | 695 | #define sata_pmp_gscr_devid(gscr)	((gscr)[SATA_PMP_GSCR_PROD_ID] >> 16) | 
|  | 696 | #define sata_pmp_gscr_rev(gscr)		(((gscr)[SATA_PMP_GSCR_REV] >> 8) & 0xff) | 
|  | 697 | #define sata_pmp_gscr_ports(gscr)	((gscr)[SATA_PMP_GSCR_PORT_INFO] & 0xf) | 
|  | 698 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 699 | #endif /* __LINUX_ATA_H__ */ |