File: atapi.h

package info (click to toggle)
linux-kernel-headers 2.5.999-test7-bk-17
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 28,268 kB
  • ctags: 214,024
  • sloc: ansic: 324,929; cpp: 783; makefile: 79; asm: 61; sh: 61
file content (370 lines) | stat: -rw-r--r-- 10,912 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
/**** vi:set ts=8 sts=8 sw=8:************************************************
 *
 * Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * 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.
 */

#include <linux/types.h>
#include <asm/byteorder.h>

/*
 * With each packet command, we allocate a buffer.
 * This is used for several packet
 * commands (Not for READ/WRITE commands).
 */
#define IDEFLOPPY_PC_BUFFER_SIZE	256
#define IDETAPE_PC_BUFFER_SIZE		256

/*
 * Packet flags bits.
 */

#define	PC_ABORT		0	/* set when an error is considered normal - we won't retry */
#define PC_WAIT_FOR_DSC		1	/* 1 when polling for DSC on a media access command */
#define PC_DMA_RECOMMENDED	2	/* 1 when we prefer to use DMA if possible */
#define	PC_DMA_IN_PROGRESS	3	/* 1 while DMA in progress */
#define	PC_DMA_ERROR		4	/* 1 when encountered problem during DMA */
#define	PC_WRITING		5	/* data direction */
#define	PC_SUPPRESS_ERROR	6	/* suppress error reporting */
#define PC_TRANSFORM		7	/* transform SCSI commands */

/* This struct get's shared between different drivers.
 */
struct atapi_packet_command {
	u8 c[12];			/* Actual packet bytes */
	char *buffer;			/* Data buffer */
	int buffer_size;		/* Size of our data buffer */
	char *current_position;		/* Pointer into the above buffer */
	int request_transfer;		/* Bytes to transfer */
	int actually_transferred;	/* Bytes actually transferred */

	unsigned long flags;		/* Status/Action bit flags: long for set_bit */

	/* FIXME: the following is ugly as hell, but the only way we can start
	 * actually to unify the code.
	 */
	/* driver specific data. */
	/* floppy/tape */
	int retries;				/* On each retry, we increment retries */
	int error;				/* Error code */
	char *b_data;				/* Pointer which runs on the buffers */
	unsigned int b_count;			/* Missing/Available data on the current buffer */
	u8 pc_buffer[IDEFLOPPY_PC_BUFFER_SIZE];	/* Temporary buffer */
	/* Called when this packet command is completed */
	void (*callback) (struct ata_device *, struct request *);

	/* only tape */
	struct bio *bio;

	/* only scsi */
	struct {
		unsigned int b_count;			/* Bytes transferred from current entry */
		struct scatterlist *sg;			/* Scatter gather table */
		struct scsi_cmnd *scsi_cmd;		/* SCSI command */
		void (*done)(struct scsi_cmnd *);	/* Scsi completion routine */
		unsigned long timeout;			/* Command timeout */
	} s;
};

/*
 *	ATAPI Status Register.
 */
typedef union {
	u8 all			: 8;
	struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
		u8 check	: 1;	/* Error occurred */
		u8 idx		: 1;	/* Reserved */
		u8 corr		: 1;	/* Correctable error occurred */
		u8 drq		: 1;	/* Data is request by the device */
		u8 dsc		: 1;	/* Media access command finished / Buffer availability */
		u8 reserved5	: 1;	/* Reserved */
		u8 drdy		: 1;	/* Ignored for ATAPI commands (ready to accept ATA command) */
		u8 bsy		: 1;	/* The device has access to the command block */
#elif defined(__BIG_ENDIAN_BITFIELD)
		u8 bsy		: 1;
		u8 drdy		: 1;
		u8 reserved5	: 1;
		u8 dsc		: 1;
		u8 drq		: 1;
		u8 corr		: 1;
		u8 idx		: 1;
		u8 check	: 1;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	} b;
} atapi_status_reg_t;

/*
 *	ATAPI error register.
 */
typedef union {
	u8 all			: 8;
	struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
		u8 ili		: 1;	/* Illegal Length Indication */
		u8 eom		: 1;	/* End Of Media Detected */
		u8 abrt		: 1;	/* Aborted command - As defined by ATA */
		u8 mcr		: 1;	/* Media Change Requested - As defined by ATA */
		u8 sense_key	: 4;	/* Sense key of the last failed packet command */
#elif defined(__BIG_ENDIAN_BITFIELD)
		u8 sense_key	: 4;
		u8 mcr		: 1;
		u8 abrt		: 1;
		u8 eom		: 1;
		u8 ili		: 1;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	} b;
} atapi_error_reg_t;

/* Currently unused, but please do not remove.  --bkz */
/*
 *	ATAPI Feature Register.
 */
typedef union {
	u8 all			: 8;
	struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
		u8 dma		: 1;	/* Using DMA or PIO */
		u8 reserved321	: 3;	/* Reserved */
		u8 reserved654	: 3;	/* Reserved (Tag Type) */
		u8 reserved7	: 1;	/* Reserved */
#elif defined(__BIG_ENDIAN_BITFIELD)
		u8 reserved7	: 1;
		u8 reserved654	: 3;
		u8 reserved321	: 3;
		u8 dma		: 1;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	} b;
} atapi_feature_reg_t;

/*
 *	ATAPI Byte Count Register.
 */
typedef union {
	u16 all			: 16;
	struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
		u8 low;			/* LSB */
		u8 high;		/* MSB */
#elif defined(__BIG_ENDIAN_BITFIELD)
		u8 high;
		u8 low;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	} b;
} atapi_bcount_reg_t;

/*
 *	ATAPI Interrupt Reason Register.
 */
typedef union {
	u8 all			: 8;
	struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
		u8 cod		: 1;	/* Information transferred is command (1) or data (0) */
		u8 io		: 1;	/* The device requests us to read (1) or write (0) */
		u8 reserved	: 6;	/* Reserved */
#elif defined(__BIG_ENDIAN_BITFIELD)
		u8 reserved	: 6;
		u8 io		: 1;
		u8 cod		: 1;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	} b;
} atapi_ireason_reg_t;

/* Currently unused, but please do not remove.  --bkz */
/*
 *	ATAPI Drive Select Register.
 */
typedef union {
	u8 all			:8;
	struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
		u8 sam_lun	:3;	/* Logical unit number */
		u8 reserved3	:1;	/* Reserved */
		u8 drv		:1;	/* The responding drive will be drive 0 (0) or drive 1 (1) */
		u8 one5		:1;	/* Should be set to 1 */
		u8 reserved6	:1;	/* Reserved */
		u8 one7		:1;	/* Should be set to 1 */
#elif defined(__BIG_ENDIAN_BITFIELD)
		u8 one7		:1;
		u8 reserved6	:1;
		u8 one5		:1;
		u8 drv		:1;
		u8 reserved3	:1;
		u8 sam_lun	:3;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	} b;
} atapi_drivesel_reg_t;

/* Currently unused, but please do not remove.  --bkz */
/*
 *	ATAPI Device Control Register.
 */
typedef union {
	u8 all			: 8;
	struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
		u8 zero0	: 1;	/* Should be set to zero */
		u8 nien		: 1;	/* Device interrupt is disabled (1) or enabled (0) */
		u8 srst		: 1;	/* ATA software reset. ATAPI devices should use the new ATAPI srst. */
		u8 one3		: 1;	/* Should be set to 1 */
		u8 reserved4567	: 4;	/* Reserved */
#elif defined(__BIG_ENDIAN_BITFIELD)
		u8 reserved4567	: 4;
		u8 one3		: 1;
		u8 srst		: 1;
		u8 nien		: 1;
		u8 zero0	: 1;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	} b;
} atapi_control_reg_t;

/*
 *	The following is used to format the general configuration word
 *	of the ATAPI IDENTIFY DEVICE command.
 */
struct atapi_id_gcw {
#if defined(__LITTLE_ENDIAN_BITFIELD)
	u8 packet_size		: 2;	/* Packet Size */
	u8 reserved234		: 3;	/* Reserved */
	u8 drq_type		: 2;	/* Command packet DRQ type */
	u8 removable		: 1;	/* Removable media */
	u8 device_type		: 5;	/* Device type */
	u8 reserved13		: 1;	/* Reserved */
	u8 protocol		: 2;	/* Protocol type */
#elif defined(__BIG_ENDIAN_BITFIELD)
	u8 protocol		: 2;
	u8 reserved13		: 1;
	u8 device_type		: 5;
	u8 removable		: 1;
	u8 drq_type		: 2;
	u8 reserved234		: 3;
	u8 packet_size		: 2;
#else
#error "Please fix <asm/byteorder.h>"
#endif
};

/*
 *	INQUIRY packet command - Data Format.
 */
typedef struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
	u8	device_type	: 5;	/* Peripheral Device Type */
	u8	reserved0_765	: 3;	/* Peripheral Qualifier - Reserved */
	u8	reserved1_6t0	: 7;	/* Reserved */
	u8	rmb		: 1;	/* Removable Medium Bit */
	u8	ansi_version	: 3;	/* ANSI Version */
	u8	ecma_version	: 3;	/* ECMA Version */
	u8	iso_version	: 2;	/* ISO Version */
	u8	response_format : 4;	/* Response Data Format */
	u8	reserved3_45	: 2;	/* Reserved */
	u8	reserved3_6	: 1;	/* TrmIOP - Reserved */
	u8	reserved3_7	: 1;	/* AENC - Reserved */
#elif defined(__BIG_ENDIAN_BITFIELD)
	u8	reserved0_765	: 3;
	u8	device_type	: 5;
	u8	rmb		: 1;
	u8	reserved1_6t0	: 7;
	u8	iso_version	: 2;
	u8	ecma_version	: 3;
	u8	ansi_version	: 3;
	u8	reserved3_7	: 1;
	u8	reserved3_6	: 1;
	u8	reserved3_45	: 2;
	u8	response_format : 4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	u8	additional_length;	/* Additional Length (total_length-4) */
	u8	rsv5, rsv6, rsv7;	/* Reserved */
	u8	vendor_id[8];		/* Vendor Identification */
	u8	product_id[16];		/* Product Identification */
	u8	revision_level[4];	/* Revision Level */
	u8	vendor_specific[20];	/* Vendor Specific - Optional */
	u8	reserved56t95[40];	/* Reserved - Optional */
					/* Additional information may be returned */
} atapi_inquiry_result_t;

/*
 *	REQUEST SENSE packet command result - Data Format.
 */
typedef struct atapi_request_sense {
#if defined(__LITTLE_ENDIAN_BITFIELD)
	u8	error_code	: 7;	/* Error Code (0x70 - current or 0x71 - deferred) */
	u8	valid		: 1;	/* The information field conforms to standard */
	u8	reserved1	: 8;	/* Reserved (Segment Number) */
	u8	sense_key	: 4;	/* Sense Key */
	u8	reserved2_4	: 1;	/* Reserved */
	u8	ili		: 1;	/* Incorrect Length Indicator */
	u8	eom		: 1;	/* End Of Medium */
	u8	filemark	: 1;	/* Filemark */
#elif defined(__BIG_ENDIAN_BITFIELD)
	u8	valid		: 1;
	u8	error_code	: 7;
	u8	reserved1	: 8;
	u8	filemark	: 1;
	u8	eom		: 1;
	u8	ili		: 1;
	u8	reserved2_4	: 1;
	u8	sense_key	: 4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
	u32	information __attribute__ ((packed));
	u8	asl;			/* Additional sense length (n-7) */
	u32	command_specific;	/* Additional command specific information */
	u8	asc;			/* Additional Sense Code */
	u8	ascq;			/* Additional Sense Code Qualifier */
	u8	replaceable_unit_code;	/* Field Replaceable Unit Code */
#if defined(__LITTLE_ENDIAN_BITFIELD)
	u8	sk_specific1	: 7;	/* Sense Key Specific */
	u8	sksv		: 1;	/* Sense Key Specific information is valid */
#elif defined(__BIG_ENDIAN_BITFIELD)
	u8	sksv		: 1;	/* Sense Key Specific information is valid */
	u8	sk_specific1	: 7;	/* Sense Key Specific */
#else
#error "Please fix <asm/byteorder.h>"
#endif
	u8	sk_specific[2];		/* Sense Key Specific */
	u8	pad[2];			/* Padding to 20 bytes */
} atapi_request_sense_result_t;


extern void atapi_init_pc(struct atapi_packet_command *pc);

extern void atapi_discard_data(struct ata_device *, unsigned int);
extern void atapi_write_zeros(struct ata_device *, unsigned int);

extern void atapi_read(struct ata_device *, u8 *, unsigned int);
extern void atapi_write(struct ata_device *, u8 *, unsigned int);

typedef enum {
	ide_wait,	/* insert rq at end of list, and wait for it */
	ide_preempt,	/* insert rq in front of current request */
	ide_end		/* insert rq at end of list, but don't wait for it */
} ide_action_t;

extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t);