Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

Bootlin logo

Elixir Cross Referencer

Loading...
  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
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
/*
 * linux/drivers/block/ide-tape.h	Version 1.5 - ALPHA	Apr  12, 1996
 *
 * Copyright (C) 1995, 1996 Gadi Oxman <gadio@netvision.net.il>
 */

/*
 * Include file for the IDE ATAPI streaming tape driver.
 *
 * This file contains various ide-tape related structures and function
 * prototypes which are already used in ide.h.
 *
 * The various compile time options are described below.
 */

#ifndef IDETAPE_H
#define IDETAPE_H 

/**************************** Tunable parameters *****************************/

/*
 *	This is probably the most important configuration option.
 *
 *	Pipelined operation mode has the potential to maximize the
 *	performance of the driver and thus to saturate the throughput
 *	to the maximum value supported by the tape.
 *
 *	In pipelined mode we are servicing requests without blocking the
 *	user backup program. For example, on a write request, we will add it
 *	to the pipeline and return without waiting for it to complete. The
 *	user program will then have enough time to prepare the next blocks
 *	while the tape is still busy working on the previous requests.
 *
 *	Pipelined operation mode is enabled by default, but since it has a
 *	few downfalls as well, you may wish to disable it.
 *	Further explanation of pipelined mode is available in ide-tape.c .
 */

#define	IDETAPE_PIPELINE	1

/*
 *	Pipelined mode parameters.
 *
 *	We try to use the minimum number of stages which is enough to
 *	keep the tape constantly streaming. To accomplish that, we implement
 *	a feedback loop around the maximum number of stages:
 *
 *	We start from MIN maximum stages (we will not even use MIN stages
 *      if we don't need them), increment it by RATE*(MAX-MIN)
 *	whenever we sense that the pipeline is empty, until we reach
 *	the optimum value or until we reach MAX.
 */
 
#define	IDETAPE_MIN_PIPELINE_STAGES		100
#define	IDETAPE_MAX_PIPELINE_STAGES		200
#define	IDETAPE_INCREASE_STAGES_RATE		0.2

/*
 *	Assuming the tape shares an interface with another device, the default
 *	behavior is to service our pending pipeline requests as soon as
 *	possible, but to gracefully postpone them in favor of the other device
 *	when the tape is busy. This has the potential to maximize our
 *	throughput and in the same time, to make efficient use of the IDE bus.
 *
 *	Note that when we transfer data to / from the tape, we co-operate with
 *	the relatively fast tape buffers and the tape will perform the
 *	actual media access in the background, without blocking the IDE
 *	bus. This means that as long as the maximum IDE bus throughput is much
 *	higher than the sum of our maximum throughput and the maximum
 *	throughput of the other device, we should probably leave the default
 *	behavior.
 *
 *	However, if it is still desired to give the other device a share even
 *	in our own (small) bus bandwidth, you can set IDETAPE_LOW_TAPE_PRIORITY
 *	to 1. This will let the other device finish *all* its pending requests
 *	before we even check if we can service our next pending request.
 */
		 
#define IDETAPE_LOW_TAPE_PRIORITY		0

/*
 *	It seems that dynamically allocating buffers of about 32KB
 *	each is doomed to fail, unless we are in or very near the
 *	initialization stage. Take care when changing this value, as it
 *	is now optimized with the design of kmalloc, so that we will not
 *	allocate parts of a page. Setting the size to 512 bytes, for example,
 *	would cause kmalloc to allocate for us 1024 bytes, and to
 *	unnecessarily waste double amount of memory.
 */

#if PAGE_SIZE == 4096
	#define	IDETAPE_ALLOCATION_BLOCK		500
#elif PAGE_SIZE == 8192
	#define	IDETAPE_ALLOCATION_BLOCK		496
#else /* ??? Not defined by linux/mm/kmalloc.c */
	#define IDETAPE_ALLOCATION_BLOCK		512
#endif

/*
 *	ide-tape currently uses two continuous buffers, each of the size of
 *	one stage. By default, those buffers are allocated at initialization
 *	time and never released, since dynamic allocation of pages bigger
 *	than PAGE_SIZE may fail as memory becomes fragmented.
 *
 *	This results in about 100 KB memory usage when the tape is idle.
 *	Setting IDETAPE_MINIMIZE_IDLE_MEMORY_USAGE to 1 will let ide-tape
 *	to dynamically allocate those buffers, resulting in about 20 KB idle
 *	memory usage.
 */
 
#define	IDETAPE_MINIMIZE_IDLE_MEMORY_USAGE	0

/*
 *	The following are used to debug the driver:
 *
 *	Setting IDETAPE_DEBUG_LOG to 1 will log driver flow control.
 *	Setting IDETAPE_DEBUG_BUGS to 1 will enable self-sanity checks in
 *	some places.
 *
 *	Setting them to 0 will restore normal operation mode:
 *
 *		1.	Disable logging normal successful operations.
 *		2.	Disable self-sanity checks.
 *		3.	Errors will still be logged, of course.
 *
 *	All the #if DEBUG code will be removed some day, when the driver
 *	is verified to be stable enough. This will make it much more
 *	esthetic.
 */
 
#define	IDETAPE_DEBUG_LOG		0
#define	IDETAPE_DEBUG_BUGS		1

/*
 *	After each failed packet command we issue a request sense command
 *	and retry the packet command IDETAPE_MAX_PC_RETRIES times.
 *
 *	Setting IDETAPE_MAX_PC_RETRIES to 0 will disable retries.
 */

#define	IDETAPE_MAX_PC_RETRIES	3

/*
 *	With each packet command, we allocate a buffer of
 *	IDETAPE_TEMP_BUFFER_SIZE bytes. This is used for several packet
 *	commands (Not for READ/WRITE commands).
 *
 *	The default below is too high - We should be using around 100 bytes
 *	typically, but I didn't check all the cases, so I rather be on the
 *	safe size.
 */
 
#define	IDETAPE_TEMP_BUFFER_SIZE 256

/*
 *	In various places in the driver, we need to allocate storage
 *	for packet commands and requests, which will remain valid while
 *	we leave the driver to wait for an interrupt or a timeout event.
 *
 *	In the corresponding ide_drive_t structure, we pre-allocate storage
 *	for IDETAPE_PC_STACK packet commands and requests. This storage is
 *	used as a circular array - Each time we reach the last entry, we
 *	warp around to the first.
 *
 *	It is crucial that we have enough entries for the maximum number
 *	of packet commands / sub-requests which we need to allocate during
 *	the handling of a specific request.
 *
 *	Follows a worse case calculation of the required storage, with a
 *	large safety margin.
 */

#define	IDETAPE_PC_STACK	20+IDETAPE_MAX_PC_RETRIES

/*
 *	DSC polling parameters.
 *
 *	Polling for DSC (a single bit in the status register) is a very
 *	important function in ide-tape. There are two cases in which we
 *	poll for DSC:
 *
 *	1.	Before a read/write packet command, to ensure that we
 *		can transfer data from/to the tape's data buffers, without
 *		causing an actual media access. In case the tape is not
 *		ready yet, we take out our request from the device
 *		request queue, so that ide.c will service requests from
 *		the other device on the same interface meanwhile.
 *
 *		We can now automatically select the "best" polling frequency.
 *		Have a look at IDETAPE_ANTICIPATE_READ_WRITE_DSC below.
 *
 *		In case you don't want to use the automatic selection,
 *		choose it to be relatively fast. The default fallback
 *		frequency is 1/50 msec.
 *
 *	2.	After the successful initialization of a "media access
 *		packet command", which is a command which can take a long
 *		time to complete (it can be several seconds or even an hour).
 *
 *		Again, we postpone our request in the middle to free the bus
 *		for the other device. The polling frequency here should be
 *		lower than the read/write frequency since those media access
 *		commands are slow. We start from a "fast" frequency -
 *		IDETAPE_DSC_FAST_MEDIA_ACCESS_FREQUENCY (one second), and
 *		if we don't receive DSC after IDETAPE_FAST_SLOW_THRESHOLD
 *		(5 minutes), we switch it to a lower frequency -
 *		IDETAPE_DSC_SLOW_MEDIA_ACCESS_FREQUENCY (1 minute).
 *		
 *	We also set a timeout for the timer, in case something goes wrong.
 *	The timeout should be longer then the maximum execution time of a
 *	tape operation. I still have to measure exactly how much time does
 *	it take to space over a far filemark, etc. It seemed that 15 minutes
 *	was way too low, so I am meanwhile setting it to a rather large
 *	timeout - 2 Hours ...
 *
 */

/*
 *	Setting IDETAPE_ANTICIPATE_READ_WRITE_DSC to 1 will allow ide-tape
 *	to cleverly select the lowest possible frequency which will
 *	not affect performance, based on the tape parameters and our operation
 *	mode. This has potential to dramatically decrease our polling load
 *	on Linux.
 *
 *	However, for the cases in which our calculation fails, setting
 *	the following option to 0 will force the use of the "fallback"
 *	polling period defined below (defaults to 50 msec).
 *
 *	In any case, the frequency will be between the "lowest" value
 *	to the "fallback" value, to ensure that our selected "best" frequency
 *	is reasonable.
 */

#define IDETAPE_ANTICIPATE_READ_WRITE_DSC	1

/*
 *	DSC timings.
 */
 
#define	IDETAPE_DSC_READ_WRITE_FALLBACK_FREQUENCY   5*HZ/100	/* 50 msec */
#define IDETAPE_DSC_READ_WRITE_LOWEST_FREQUENCY	30*HZ/100	/* 300 msec */
#define	IDETAPE_DSC_FAST_MEDIA_ACCESS_FREQUENCY	1*HZ		/* 1 second */
#define	IDETAPE_FAST_SLOW_THRESHOLD		5*60*HZ		/* 5 minutes */
#define IDETAPE_DSC_SLOW_MEDIA_ACCESS_FREQUENCY	60*HZ		/* 1 minute */
#define	IDETAPE_DSC_TIMEOUT			2*60*60*HZ	/* 2 hours */

/*************************** End of tunable parameters ***********************/

/*
 *	Definitions which are already needed in ide.h
 */

/*
 *	Current character device data transfer direction.
 */
  
typedef enum {idetape_direction_none,idetape_direction_read,idetape_direction_write} chrdev_direction_t;

struct ide_drive_s;				/* Forward declaration - Will be defined later in ide.h */
typedef void (idetape_pc_completed_t)(struct ide_drive_s *);

/*
 *	Our view of a packet command.
 */

typedef struct idetape_packet_command_s {
	byte c [12];				/* Actual packet bytes */
	
	byte retries;				/* On each retry, we increment retries */
	byte error;				/* Error code */
	byte abort;				/* Set when an error is considered normal - We won't retry */
	byte wait_for_dsc;			/* 1 When polling for DSC on a media access command */
	byte dma_recommended;			/* 1 when we prefer to use DMA if possible */
	byte dma_in_progress;			/* 1 while DMA in progress */
	byte dma_error;				/* 1 when encountered problem during DMA */
	unsigned long request_transfer;		/* Bytes to transfer */
	unsigned long actually_transferred; 	/* Bytes actually transferred */
	unsigned long buffer_size;		/* Size of our data buffer */
	byte *buffer;				/* Data buffer */
	byte *current_position;			/* Pointer into the above buffer */
	byte writing;				/* Data direction */		
	idetape_pc_completed_t *callback; 	/* Called when this packet command is completed */
	byte temp_buffer [IDETAPE_TEMP_BUFFER_SIZE];	/* Temporary buffer */
} idetape_packet_command_t;

/*
 *	Capabilities and Mechanical Status Page
 */

typedef struct {
	unsigned page_code	:6;	/* Page code - Should be 0x2a */
	unsigned reserved1_67	:2;
	byte page_length;		/* Page Length - Should be 0x12 */
	byte reserved2;	
	byte reserved3;	
	unsigned ro		:1;	/* Read Only Mode */
	unsigned reserved4_1234	:4;
	unsigned sprev		:1;	/* Supports SPACE in the reverse direction */
	unsigned reserved4_67	:2;
	unsigned reserved5_012	:3;
	unsigned efmt		:1;	/* Supports ERASE command initiated formatting */
	unsigned reserved5_4	:1;
	unsigned qfa		:1;	/* Supports the QFA two partition formats */
	unsigned reserved5_67	:2;
	unsigned lock		:1;	/* Supports locking the volume */
	unsigned locked		:1;	/* The volume is locked */
	unsigned prevent	:1;	/* The device defaults in the prevent state after power up */	
	unsigned eject		:1;	/* The device can eject the volume */
	unsigned reserved6_45	:2;	/* Reserved */	
	unsigned ecc		:1;	/* Supports error correction */
	unsigned cmprs		:1;	/* Supports data compression */
	unsigned reserved7_0	:1;
	unsigned blk512		:1;	/* Supports 512 bytes block size */
	unsigned blk1024	:1;	/* Supports 1024 bytes block size */
	unsigned reserved7_3_6	:4;
	unsigned slowb		:1;	/* The device restricts the byte count for PIO */
					/* transfers for slow buffer memory ??? */
	unsigned short max_speed;	/* Maximum speed supported in KBps */
	byte reserved10;
	byte reserved11;
	unsigned short ctl;		/* Continuous Transfer Limit in blocks */
	unsigned short speed;		/* Current Speed, in KBps */
	unsigned short buffer_size;	/* Buffer Size, in 512 bytes */
	byte reserved18;
	byte reserved19;
} idetape_capabilities_page_t;

/*
 *	A pipeline stage contains several small buffers of type
 *	idetape_buffer_head_t. This is necessary since dynamical allocation
 *	of large (32 KB or so) continuous memory blocks will usually fail.
 */
 
typedef struct idetape_buffer_head_s {
	char *data;					/* Pointer to data (512 bytes by default) */
	struct idetape_buffer_head_s *next;
} idetape_buffer_head_t;

/*
 *	A pipeline stage.
 *
 *	In a pipeline stage we have a request, pointer to a list of small
 *	buffers, and pointers to the near stages.
 */

typedef struct idetape_pipeline_stage_s {
	struct request rq;				/* The corresponding request */
	idetape_buffer_head_t *bh;			/* The data buffers */
	struct idetape_pipeline_stage_s *next,*prev;	/* Pointers to the next and previous stages */
} idetape_pipeline_stage_t;

/*
 *	Most of our global data which we need to save even as we leave the
 *	driver due to an interrupt or a timer event is stored in a variable
 *	of type tape_info, defined below.
 *
 *	Additional global variables which provide the link between the
 *	character device interface to this structure are defined in
 *	ide-tape.c
 */
 
typedef struct {	

	/*
	 *	Since a typical character device operation requires more
	 *	than one packet command, we provide here enough memory
	 *	for the maximum of interconnected packet commands.
	 *	The packet commands are stored in the circular array pc_stack.
	 *	pc_stack_index points to the last used entry, and warps around
	 *	to the start when we get to the last array entry.
	 *
	 *	pc points to the current processed packet command.
	 *
	 *	failed_pc points to the last failed packet command, or contains
	 *	NULL if we do not need to retry any packet command. This is
	 *	required since an additional packet command is needed before the
	 *	retry, to get detailed information on what went wrong.
      	 */

	idetape_packet_command_t *pc;		/* Current packet command */
	idetape_packet_command_t *failed_pc; 	/* Last failed packet command */
	idetape_packet_command_t pc_stack [IDETAPE_PC_STACK]; /* Packet command stack */
	byte pc_stack_index;			/* Next free packet command storage space */

	/* 
	 *	The Linux ide driver basically traverses the request lists
	 *	of the ide block devices, finds the next request, completes
	 *	it, and passes to the next one. This is done in ide_do_request.
	 *
	 *	In this regard, ide-tape.c is fully compatible with the rest of
	 *	the ide driver - From the point of view of ide.c, we are just
	 *	another ide block device which receives requests and completes
	 *	them.
	 *
	 *	However, our requests don't originate in the buffer cache but
	 *	rather in ide-tape.c itself. Here we provide safe storage for
	 *	such requests.
	 */

	struct request rq_stack [IDETAPE_PC_STACK];
	byte rq_stack_index;			/* We implement a circular array */

	/*
	 *	While polling for DSC we use postponed_rq to postpone the
	 *	current request so that ide.c will be able to service
	 *	pending requests on the other device. Note that at most
	 *	we will have only one DSC (usually data transfer) request
	 *	in the device request queue. Additional request can be
	 *	queued in our internal pipeline, but they will be visible
	 *	to ide.c only one at a time.
	 */

	struct request *postponed_rq;
	
	/*
	 *	DSC polling variables.
	 */
	 
	byte dsc_count;				/* We received DSC dsc_count times in a row */
	unsigned long dsc_polling_start;	/* The time in which we started polling for DSC */
	struct timer_list dsc_timer;		/* Timer used to poll for dsc */

	/*
	 *	We can now be much more clever in our selection of the
	 *	read/write polling frequency. This is used along with
	 *	the compile time option IDETAPE_ANTICIPATE_DSC.
	 */
 
	unsigned long best_dsc_rw_frequency;	/* Read/Write dsc polling frequency */

	unsigned long dsc_polling_frequency;	/* The current polling frequency */
	unsigned long dsc_timeout;		/* Maximum waiting time */
	byte dsc_received;			/* Set when we receive DSC */

	byte request_status;
	byte last_status;			/* Contents of the tape status register */
						/* before the current request (saved for us */
						/* by ide.c) */
	/*
	 *	After an ATAPI software reset, the status register will be
	 *	locked, and thus we need to ignore it when checking DSC for
	 *	the first time.
	 */
	 
	byte reset_issued;

	/* Position information */
	
	byte partition_num;			/* Currently not used */
	unsigned long block_address;		/* Current block */
	byte block_address_valid;		/* 0 When the tape position is unknown */
						/* (To the tape or to us) */
	/* Last error information */
	
	byte sense_key,asc,ascq;

	/* Character device operation */

	chrdev_direction_t chrdev_direction;	/* Current character device data transfer direction */
	byte busy;				/* Device already opened */

	/* Device information */
	
	unsigned short tape_block_size;			/* Usually 512 or 1024 bytes */
	idetape_capabilities_page_t capabilities;	/* Copy of the tape's Capabilities and Mechanical Page */

	/*
	 *	Active data transfer request parameters.
	 *
	 *	At most, there is only one ide-tape originated data transfer
	 *	request in the device request queue. This allows ide.c to
	 *	easily service requests from the other device when we
	 *	postpone our active request. In the pipelined operation
	 *	mode, we use our internal pipeline structure to hold
	 *	more data requests.
	 *
	 *	The data buffer size is chosen based on the tape's
	 *	recommendation.
	 */
	
	struct request *active_data_request;	/* Pointer to the request which is waiting in the device request queue */
	char *data_buffer;			/* The corresponding data buffer (for read/write requests) */
	int data_buffer_size;			/* Data buffer size (chosen based on the tape's recommendation */

	char *merge_buffer;			/* Temporary buffer for user <-> kernel space data transfer */
	int merge_buffer_offset;
	int merge_buffer_size;
	
	/*
	 *	Pipeline parameters.
	 *
	 *	To accomplish non-pipelined mode, we simply set the following
	 *	variables to zero (or NULL, where appropriate).
	 */
		
	int current_number_of_stages;		/* Number of currently used stages */
	int max_number_of_stages;		/* We will not allocate more than this number of stages */
	idetape_pipeline_stage_t *first_stage;	/* The first stage which will be removed from the pipeline */
	idetape_pipeline_stage_t *active_stage;	/* The currently active stage */
	idetape_pipeline_stage_t *next_stage;	/* Will be serviced after the currently active request */
	idetape_pipeline_stage_t *last_stage;	/* New requests will be added to the pipeline here */
	int error_in_pipeline_stage;		/* Set when an error was detected in one of the pipeline stages */	
	
} idetape_tape_t;

/*
 *	The following is used to have a quick look at the tape's status
 *	register between requests of the other device.
 */
 
#define POLL_HWIF_TAPE_DRIVE							\
	if (hwif->tape_drive != NULL) {						\
		if (hwif->tape_drive->tape.request_status) {			\
			SELECT_DRIVE(hwif,hwif->tape_drive);			\
			hwif->tape_drive->tape.last_status=GET_STAT();		\
			hwif->tape_drive->tape.request_status=0;		\
		}								\
	}

#endif /* IDETAPE_H */