| 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, | 
 | 43 |  | 
 | 44 | 	ATA_ID_WORDS		= 256, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 45 | 	ATA_ID_SERNO_OFS	= 10, | 
| Alan Cox | 11e29e2 | 2005-10-21 18:46:32 -0400 | [diff] [blame] | 46 | 	ATA_ID_FW_REV_OFS	= 23, | 
 | 47 | 	ATA_ID_PROD_OFS		= 27, | 
 | 48 | 	ATA_ID_OLD_PIO_MODES	= 51, | 
 | 49 | 	ATA_ID_FIELD_VALID	= 53, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 50 | 	ATA_ID_MWDMA_MODES	= 63, | 
| Alan Cox | 11e29e2 | 2005-10-21 18:46:32 -0400 | [diff] [blame] | 51 | 	ATA_ID_PIO_MODES	= 64, | 
 | 52 | 	ATA_ID_EIDE_DMA_MIN	= 65, | 
 | 53 | 	ATA_ID_EIDE_PIO		= 67, | 
 | 54 | 	ATA_ID_EIDE_PIO_IORDY	= 68, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 55 | 	ATA_ID_UDMA_MODES	= 88, | 
| Alan Cox | 11e29e2 | 2005-10-21 18:46:32 -0400 | [diff] [blame] | 56 | 	ATA_ID_MAJOR_VER	= 80, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 57 | 	ATA_ID_PIO4		= (1 << 1), | 
 | 58 |  | 
 | 59 | 	ATA_PCI_CTL_OFS		= 2, | 
 | 60 | 	ATA_SERNO_LEN		= 20, | 
 | 61 | 	ATA_UDMA0		= (1 << 0), | 
 | 62 | 	ATA_UDMA1		= ATA_UDMA0 | (1 << 1), | 
 | 63 | 	ATA_UDMA2		= ATA_UDMA1 | (1 << 2), | 
 | 64 | 	ATA_UDMA3		= ATA_UDMA2 | (1 << 3), | 
 | 65 | 	ATA_UDMA4		= ATA_UDMA3 | (1 << 4), | 
 | 66 | 	ATA_UDMA5		= ATA_UDMA4 | (1 << 5), | 
 | 67 | 	ATA_UDMA6		= ATA_UDMA5 | (1 << 6), | 
 | 68 | 	ATA_UDMA7		= ATA_UDMA6 | (1 << 7), | 
 | 69 | 	/* ATA_UDMA7 is just for completeness... doesn't exist (yet?).  */ | 
 | 70 |  | 
 | 71 | 	ATA_UDMA_MASK_40C	= ATA_UDMA2,	/* udma0-2 */ | 
 | 72 |  | 
 | 73 | 	/* DMA-related */ | 
 | 74 | 	ATA_PRD_SZ		= 8, | 
 | 75 | 	ATA_PRD_TBL_SZ		= (ATA_MAX_PRD * ATA_PRD_SZ), | 
 | 76 | 	ATA_PRD_EOT		= (1 << 31),	/* end-of-table flag */ | 
 | 77 |  | 
 | 78 | 	ATA_DMA_TABLE_OFS	= 4, | 
 | 79 | 	ATA_DMA_STATUS		= 2, | 
 | 80 | 	ATA_DMA_CMD		= 0, | 
 | 81 | 	ATA_DMA_WR		= (1 << 3), | 
 | 82 | 	ATA_DMA_START		= (1 << 0), | 
 | 83 | 	ATA_DMA_INTR		= (1 << 2), | 
 | 84 | 	ATA_DMA_ERR		= (1 << 1), | 
 | 85 | 	ATA_DMA_ACTIVE		= (1 << 0), | 
 | 86 |  | 
 | 87 | 	/* bits in ATA command block registers */ | 
 | 88 | 	ATA_HOB			= (1 << 7),	/* LBA48 selector */ | 
 | 89 | 	ATA_NIEN		= (1 << 1),	/* disable-irq flag */ | 
 | 90 | 	ATA_LBA			= (1 << 6),	/* LBA28 selector */ | 
 | 91 | 	ATA_DEV1		= (1 << 4),	/* Select Device 1 (slave) */ | 
 | 92 | 	ATA_DEVICE_OBS		= (1 << 7) | (1 << 5), /* obs bits in dev reg */ | 
 | 93 | 	ATA_DEVCTL_OBS		= (1 << 3),	/* obsolete bit in devctl reg */ | 
 | 94 | 	ATA_BUSY		= (1 << 7),	/* BSY status bit */ | 
 | 95 | 	ATA_DRDY		= (1 << 6),	/* device ready */ | 
 | 96 | 	ATA_DF			= (1 << 5),	/* device fault */ | 
 | 97 | 	ATA_DRQ			= (1 << 3),	/* data request i/o */ | 
 | 98 | 	ATA_ERR			= (1 << 0),	/* have an error */ | 
 | 99 | 	ATA_SRST		= (1 << 2),	/* software reset */ | 
| Tejun Heo | 9be1e97 | 2006-05-15 20:58:17 +0900 | [diff] [blame] | 100 | 	ATA_ICRC		= (1 << 7),	/* interface CRC error */ | 
 | 101 | 	ATA_UNC			= (1 << 6),	/* uncorrectable media error */ | 
 | 102 | 	ATA_IDNF		= (1 << 4),	/* ID not found */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 103 | 	ATA_ABORTED		= (1 << 2),	/* command aborted */ | 
 | 104 |  | 
 | 105 | 	/* ATA command block registers */ | 
 | 106 | 	ATA_REG_DATA		= 0x00, | 
 | 107 | 	ATA_REG_ERR		= 0x01, | 
 | 108 | 	ATA_REG_NSECT		= 0x02, | 
 | 109 | 	ATA_REG_LBAL		= 0x03, | 
 | 110 | 	ATA_REG_LBAM		= 0x04, | 
 | 111 | 	ATA_REG_LBAH		= 0x05, | 
 | 112 | 	ATA_REG_DEVICE		= 0x06, | 
 | 113 | 	ATA_REG_STATUS		= 0x07, | 
 | 114 |  | 
 | 115 | 	ATA_REG_FEATURE		= ATA_REG_ERR, /* and their aliases */ | 
 | 116 | 	ATA_REG_CMD		= ATA_REG_STATUS, | 
 | 117 | 	ATA_REG_BYTEL		= ATA_REG_LBAM, | 
 | 118 | 	ATA_REG_BYTEH		= ATA_REG_LBAH, | 
 | 119 | 	ATA_REG_DEVSEL		= ATA_REG_DEVICE, | 
 | 120 | 	ATA_REG_IRQ		= ATA_REG_NSECT, | 
 | 121 |  | 
 | 122 | 	/* ATA device commands */ | 
 | 123 | 	ATA_CMD_CHK_POWER	= 0xE5, /* check power mode */ | 
| Douglas Gilbert | 972dcaf | 2005-08-11 03:35:53 -0400 | [diff] [blame] | 124 | 	ATA_CMD_STANDBY		= 0xE2, /* place in standby power mode */ | 
 | 125 | 	ATA_CMD_IDLE		= 0xE3, /* place in idle power mode */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 126 | 	ATA_CMD_EDD		= 0x90,	/* execute device diagnostic */ | 
 | 127 | 	ATA_CMD_FLUSH		= 0xE7, | 
 | 128 | 	ATA_CMD_FLUSH_EXT	= 0xEA, | 
 | 129 | 	ATA_CMD_ID_ATA		= 0xEC, | 
 | 130 | 	ATA_CMD_ID_ATAPI	= 0xA1, | 
 | 131 | 	ATA_CMD_READ		= 0xC8, | 
 | 132 | 	ATA_CMD_READ_EXT	= 0x25, | 
 | 133 | 	ATA_CMD_WRITE		= 0xCA, | 
 | 134 | 	ATA_CMD_WRITE_EXT	= 0x35, | 
| Tejun Heo | 9a3dccc | 2006-01-06 09:56:18 +0100 | [diff] [blame] | 135 | 	ATA_CMD_WRITE_FUA_EXT	= 0x3D, | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 136 | 	ATA_CMD_FPDMA_READ	= 0x60, | 
 | 137 | 	ATA_CMD_FPDMA_WRITE	= 0x61, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 138 | 	ATA_CMD_PIO_READ	= 0x20, | 
 | 139 | 	ATA_CMD_PIO_READ_EXT	= 0x24, | 
 | 140 | 	ATA_CMD_PIO_WRITE	= 0x30, | 
 | 141 | 	ATA_CMD_PIO_WRITE_EXT	= 0x34, | 
| Albert Lee | 8cbd6df | 2005-10-12 15:06:27 +0800 | [diff] [blame] | 142 | 	ATA_CMD_READ_MULTI	= 0xC4, | 
 | 143 | 	ATA_CMD_READ_MULTI_EXT	= 0x29, | 
 | 144 | 	ATA_CMD_WRITE_MULTI	= 0xC5, | 
 | 145 | 	ATA_CMD_WRITE_MULTI_EXT	= 0x39, | 
| Tejun Heo | 9a3dccc | 2006-01-06 09:56:18 +0100 | [diff] [blame] | 146 | 	ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 147 | 	ATA_CMD_SET_FEATURES	= 0xEF, | 
 | 148 | 	ATA_CMD_PACKET		= 0xA0, | 
 | 149 | 	ATA_CMD_VERIFY		= 0x40, | 
 | 150 | 	ATA_CMD_VERIFY_EXT	= 0x42, | 
| Jens Axboe | 9b84754 | 2006-01-06 09:28:07 +0100 | [diff] [blame] | 151 |  	ATA_CMD_STANDBYNOW1	= 0xE0, | 
 | 152 |  	ATA_CMD_IDLEIMMEDIATE	= 0xE1, | 
| Albert Lee | 8bf62ec | 2005-05-12 15:29:42 -0400 | [diff] [blame] | 153 | 	ATA_CMD_INIT_DEV_PARAMS	= 0x91, | 
| Alan Cox | b678272 | 2006-03-21 15:52:49 +0000 | [diff] [blame] | 154 | 	ATA_CMD_READ_NATIVE_MAX	= 0xF8, | 
 | 155 | 	ATA_CMD_READ_NATIVE_MAX_EXT = 0x27, | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 156 | 	ATA_CMD_READ_LOG_EXT	= 0x2f, | 
 | 157 |  | 
 | 158 | 	/* READ_LOG_EXT pages */ | 
 | 159 | 	ATA_LOG_SATA_NCQ	= 0x10, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 160 |  | 
 | 161 | 	/* SETFEATURES stuff */ | 
 | 162 | 	SETFEATURES_XFER	= 0x03, | 
 | 163 | 	XFER_UDMA_7		= 0x47, | 
 | 164 | 	XFER_UDMA_6		= 0x46, | 
 | 165 | 	XFER_UDMA_5		= 0x45, | 
 | 166 | 	XFER_UDMA_4		= 0x44, | 
 | 167 | 	XFER_UDMA_3		= 0x43, | 
 | 168 | 	XFER_UDMA_2		= 0x42, | 
 | 169 | 	XFER_UDMA_1		= 0x41, | 
 | 170 | 	XFER_UDMA_0		= 0x40, | 
 | 171 | 	XFER_MW_DMA_2		= 0x22, | 
 | 172 | 	XFER_MW_DMA_1		= 0x21, | 
 | 173 | 	XFER_MW_DMA_0		= 0x20, | 
| Alan Cox | b4b52db | 2005-09-26 12:48:41 +0100 | [diff] [blame] | 174 | 	XFER_SW_DMA_2		= 0x12, | 
 | 175 | 	XFER_SW_DMA_1		= 0x11, | 
 | 176 | 	XFER_SW_DMA_0		= 0x10, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 177 | 	XFER_PIO_4		= 0x0C, | 
 | 178 | 	XFER_PIO_3		= 0x0B, | 
 | 179 | 	XFER_PIO_2		= 0x0A, | 
 | 180 | 	XFER_PIO_1		= 0x09, | 
 | 181 | 	XFER_PIO_0		= 0x08, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 182 | 	XFER_PIO_SLOW		= 0x00, | 
 | 183 |  | 
| zhao, forrest | 3057ac3 | 2006-06-12 12:01:34 +0800 | [diff] [blame] | 184 | 	SETFEATURES_WC_ON	= 0x02, /* Enable write cache */ | 
 | 185 | 	SETFEATURES_WC_OFF	= 0x82, /* Disable write cache */ | 
 | 186 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 187 | 	/* ATAPI stuff */ | 
 | 188 | 	ATAPI_PKT_DMA		= (1 << 0), | 
 | 189 | 	ATAPI_DMADIR		= (1 << 2),	/* ATAPI data dir: | 
 | 190 | 						   0=to device, 1=to host */ | 
 | 191 | 	ATAPI_CDB_LEN		= 16, | 
 | 192 |  | 
 | 193 | 	/* cable types */ | 
 | 194 | 	ATA_CBL_NONE		= 0, | 
 | 195 | 	ATA_CBL_PATA40		= 1, | 
 | 196 | 	ATA_CBL_PATA80		= 2, | 
 | 197 | 	ATA_CBL_PATA_UNK	= 3, | 
 | 198 | 	ATA_CBL_SATA		= 4, | 
 | 199 |  | 
 | 200 | 	/* SATA Status and Control Registers */ | 
 | 201 | 	SCR_STATUS		= 0, | 
 | 202 | 	SCR_ERROR		= 1, | 
 | 203 | 	SCR_CONTROL		= 2, | 
 | 204 | 	SCR_ACTIVE		= 3, | 
 | 205 | 	SCR_NOTIFICATION	= 4, | 
 | 206 |  | 
| Tejun Heo | 9be1e97 | 2006-05-15 20:58:17 +0900 | [diff] [blame] | 207 | 	/* SError bits */ | 
 | 208 | 	SERR_DATA_RECOVERED	= (1 << 0), /* recovered data error */ | 
 | 209 | 	SERR_COMM_RECOVERED	= (1 << 1), /* recovered comm failure */ | 
 | 210 | 	SERR_DATA		= (1 << 8), /* unrecovered data error */ | 
 | 211 | 	SERR_PERSISTENT		= (1 << 9), /* persistent data/comm error */ | 
 | 212 | 	SERR_PROTOCOL		= (1 << 10), /* protocol violation */ | 
 | 213 | 	SERR_INTERNAL		= (1 << 11), /* host internal error */ | 
 | 214 | 	SERR_PHYRDY_CHG		= (1 << 16), /* PHY RDY changed */ | 
 | 215 | 	SERR_DEV_XCHG		= (1 << 26), /* device exchanged */ | 
 | 216 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 217 | 	/* struct ata_taskfile flags */ | 
 | 218 | 	ATA_TFLAG_LBA48		= (1 << 0), /* enable 48-bit LBA and "HOB" */ | 
 | 219 | 	ATA_TFLAG_ISADDR	= (1 << 1), /* enable r/w to nsect/lba regs */ | 
 | 220 | 	ATA_TFLAG_DEVICE	= (1 << 2), /* enable r/w to device reg */ | 
 | 221 | 	ATA_TFLAG_WRITE		= (1 << 3), /* data dir: host->dev==1 (write) */ | 
| Albert Lee | 8bf62ec | 2005-05-12 15:29:42 -0400 | [diff] [blame] | 222 | 	ATA_TFLAG_LBA		= (1 << 4), /* enable LBA */ | 
| Tejun Heo | 9a3dccc | 2006-01-06 09:56:18 +0100 | [diff] [blame] | 223 | 	ATA_TFLAG_FUA		= (1 << 5), /* enable FUA */ | 
| Jeff Garzik | ea9b395 | 2006-01-17 10:29:06 -0500 | [diff] [blame] | 224 | 	ATA_TFLAG_POLLING	= (1 << 6), /* set nIEN to 1 and use polling */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 225 | }; | 
 | 226 |  | 
 | 227 | enum ata_tf_protocols { | 
 | 228 | 	/* ATA taskfile protocols */ | 
 | 229 | 	ATA_PROT_UNKNOWN,	/* unknown/invalid */ | 
 | 230 | 	ATA_PROT_NODATA,	/* no data */ | 
 | 231 | 	ATA_PROT_PIO,		/* PIO single sector */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 232 | 	ATA_PROT_DMA,		/* DMA */ | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 233 | 	ATA_PROT_NCQ,		/* NCQ */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 234 | 	ATA_PROT_ATAPI,		/* packet command, PIO data xfer*/ | 
 | 235 | 	ATA_PROT_ATAPI_NODATA,	/* packet command, no data */ | 
 | 236 | 	ATA_PROT_ATAPI_DMA,	/* packet command with special DMA sauce */ | 
 | 237 | }; | 
 | 238 |  | 
 | 239 | enum ata_ioctls { | 
 | 240 | 	ATA_IOC_GET_IO32	= 0x309, | 
 | 241 | 	ATA_IOC_SET_IO32	= 0x324, | 
 | 242 | }; | 
 | 243 |  | 
 | 244 | /* core structures */ | 
 | 245 |  | 
 | 246 | struct ata_prd { | 
 | 247 | 	u32			addr; | 
 | 248 | 	u32			flags_len; | 
 | 249 | }; | 
 | 250 |  | 
 | 251 | struct ata_taskfile { | 
 | 252 | 	unsigned long		flags;		/* ATA_TFLAG_xxx */ | 
 | 253 | 	u8			protocol;	/* ATA_PROT_xxx */ | 
 | 254 |  | 
 | 255 | 	u8			ctl;		/* control reg */ | 
 | 256 |  | 
 | 257 | 	u8			hob_feature;	/* additional data */ | 
 | 258 | 	u8			hob_nsect;	/* to support LBA48 */ | 
 | 259 | 	u8			hob_lbal; | 
 | 260 | 	u8			hob_lbam; | 
 | 261 | 	u8			hob_lbah; | 
 | 262 |  | 
 | 263 | 	u8			feature; | 
 | 264 | 	u8			nsect; | 
 | 265 | 	u8			lbal; | 
 | 266 | 	u8			lbam; | 
 | 267 | 	u8			lbah; | 
 | 268 |  | 
 | 269 | 	u8			device; | 
 | 270 |  | 
 | 271 | 	u8			command;	/* IO operation */ | 
 | 272 | }; | 
 | 273 |  | 
 | 274 | #define ata_id_is_ata(id)	(((id)[0] & (1 << 15)) == 0) | 
| Alan Cox | b678272 | 2006-03-21 15:52:49 +0000 | [diff] [blame] | 275 | #define ata_id_is_cfa(id)	((id)[0] == 0x848A) | 
| Brad Campbell | 6f2f381 | 2005-05-12 15:07:47 -0400 | [diff] [blame] | 276 | #define ata_id_is_sata(id)	((id)[93] == 0) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 277 | #define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6)) | 
 | 278 | #define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5)) | 
| Alan Cox | b678272 | 2006-03-21 15:52:49 +0000 | [diff] [blame] | 279 | #define ata_id_hpa_enabled(id)	((id)[85] & (1 << 10)) | 
| Tejun Heo | 9a3dccc | 2006-01-06 09:56:18 +0100 | [diff] [blame] | 280 | #define ata_id_has_fua(id)	((id)[84] & (1 << 6)) | 
 | 281 | #define ata_id_has_flush(id)	((id)[83] & (1 << 12)) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 282 | #define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13)) | 
 | 283 | #define ata_id_has_lba48(id)	((id)[83] & (1 << 10)) | 
| Alan Cox | b678272 | 2006-03-21 15:52:49 +0000 | [diff] [blame] | 284 | #define ata_id_has_hpa(id)	((id)[82] & (1 << 10)) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 285 | #define ata_id_has_wcache(id)	((id)[82] & (1 << 5)) | 
 | 286 | #define ata_id_has_pm(id)	((id)[82] & (1 << 3)) | 
 | 287 | #define ata_id_has_lba(id)	((id)[49] & (1 << 9)) | 
 | 288 | #define ata_id_has_dma(id)	((id)[49] & (1 << 8)) | 
| Tejun Heo | 88e4903 | 2006-05-15 21:03:38 +0900 | [diff] [blame] | 289 | #define ata_id_has_ncq(id)	((id)[76] & (1 << 8)) | 
 | 290 | #define ata_id_queue_depth(id)	(((id)[75] & 0x1f) + 1) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 291 | #define ata_id_removeable(id)	((id)[0] & (1 << 7)) | 
| Alan Cox | b678272 | 2006-03-21 15:52:49 +0000 | [diff] [blame] | 292 | #define ata_id_has_dword_io(id)	((id)[50] & (1 << 0)) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 293 | #define ata_id_u32(id,n)	\ | 
 | 294 | 	(((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)])) | 
 | 295 | #define ata_id_u64(id,n)	\ | 
 | 296 | 	( ((u64) (id)[(n) + 3] << 48) |	\ | 
 | 297 | 	  ((u64) (id)[(n) + 2] << 32) |	\ | 
 | 298 | 	  ((u64) (id)[(n) + 1] << 16) |	\ | 
 | 299 | 	  ((u64) (id)[(n) + 0]) ) | 
 | 300 |  | 
| Albert Lee | 312f7da | 2005-09-27 17:38:03 +0800 | [diff] [blame] | 301 | #define ata_id_cdb_intr(id)	(((id)[0] & 0x60) == 0x20) | 
 | 302 |  | 
| Tejun Heo | 3d2ca91 | 2006-02-12 22:47:04 +0900 | [diff] [blame] | 303 | static inline unsigned int ata_id_major_version(const u16 *id) | 
 | 304 | { | 
 | 305 | 	unsigned int mver; | 
 | 306 |  | 
 | 307 | 	for (mver = 14; mver >= 1; mver--) | 
 | 308 | 		if (id[ATA_ID_MAJOR_VER] & (1 << mver)) | 
 | 309 | 			break; | 
 | 310 | 	return mver; | 
 | 311 | } | 
 | 312 |  | 
| Jeff Garzik | 057ace5 | 2005-10-22 14:27:05 -0400 | [diff] [blame] | 313 | static inline int ata_id_current_chs_valid(const u16 *id) | 
| Albert Lee | 8bf62ec | 2005-05-12 15:29:42 -0400 | [diff] [blame] | 314 | { | 
 | 315 | 	/* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command  | 
 | 316 | 	   has not been issued to the device then the values of  | 
 | 317 | 	   id[54] to id[56] are vendor specific. */ | 
 | 318 | 	return (id[53] & 0x01) && /* Current translation valid */ | 
 | 319 | 		id[54] &&  /* cylinders in current translation */ | 
 | 320 | 		id[55] &&  /* heads in current translation */ | 
 | 321 | 		id[55] <= 16 && | 
 | 322 | 		id[56];    /* sectors in current translation */ | 
 | 323 | } | 
 | 324 |  | 
| Jeff Garzik | 057ace5 | 2005-10-22 14:27:05 -0400 | [diff] [blame] | 325 | static inline int atapi_cdb_len(const u16 *dev_id) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 326 | { | 
 | 327 | 	u16 tmp = dev_id[0] & 0x3; | 
 | 328 | 	switch (tmp) { | 
 | 329 | 	case 0:		return 12; | 
 | 330 | 	case 1:		return 16; | 
 | 331 | 	default:	return -1; | 
 | 332 | 	} | 
 | 333 | } | 
 | 334 |  | 
| Jeff Garzik | 057ace5 | 2005-10-22 14:27:05 -0400 | [diff] [blame] | 335 | static inline int is_atapi_taskfile(const struct ata_taskfile *tf) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 336 | { | 
 | 337 | 	return (tf->protocol == ATA_PROT_ATAPI) || | 
 | 338 | 	       (tf->protocol == ATA_PROT_ATAPI_NODATA) || | 
 | 339 | 	       (tf->protocol == ATA_PROT_ATAPI_DMA); | 
 | 340 | } | 
 | 341 |  | 
| Albert Lee | 07f6f7d | 2005-11-01 19:33:20 +0800 | [diff] [blame] | 342 | static inline int is_multi_taskfile(struct ata_taskfile *tf) | 
 | 343 | { | 
 | 344 | 	return (tf->command == ATA_CMD_READ_MULTI) || | 
 | 345 | 	       (tf->command == ATA_CMD_WRITE_MULTI) || | 
 | 346 | 	       (tf->command == ATA_CMD_READ_MULTI_EXT) || | 
| Albert Lee | c2956a3 | 2006-03-03 10:34:05 +0800 | [diff] [blame] | 347 | 	       (tf->command == ATA_CMD_WRITE_MULTI_EXT) || | 
 | 348 | 	       (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT); | 
| Albert Lee | 07f6f7d | 2005-11-01 19:33:20 +0800 | [diff] [blame] | 349 | } | 
 | 350 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 351 | static inline int ata_ok(u8 status) | 
 | 352 | { | 
 | 353 | 	return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR)) | 
 | 354 | 			== ATA_DRDY); | 
 | 355 | } | 
 | 356 |  | 
| Albert Lee | c6a33e2 | 2005-10-12 15:12:26 +0800 | [diff] [blame] | 357 | static inline int lba_28_ok(u64 block, u32 n_block) | 
 | 358 | { | 
 | 359 | 	/* check the ending block number */ | 
 | 360 | 	return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256); | 
 | 361 | } | 
 | 362 |  | 
 | 363 | static inline int lba_48_ok(u64 block, u32 n_block) | 
 | 364 | { | 
 | 365 | 	/* check the ending block number */ | 
 | 366 | 	return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536); | 
 | 367 | } | 
 | 368 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 369 | #endif /* __LINUX_ATA_H__ */ |