patch-1.3.46 linux/drivers/block/ide-tape.h
Next file: linux/drivers/block/ide.c
Previous file: linux/drivers/block/ide-tape.c
Back to the patch index
Back to the overall index
- Lines: 328
- Date:
Mon Dec 11 08:49:54 1995
- Orig file:
v1.3.45/linux/drivers/block/ide-tape.h
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v1.3.45/linux/drivers/block/ide-tape.h linux/drivers/block/ide-tape.h
@@ -0,0 +1,327 @@
+/*
+ * linux/drivers/block/ide-tape.h Version 1.0 - ALPHA Dec 3, 1995
+ *
+ * Copyright (C) 1995 Gadi Oxman <tgud@tochnapc2.technion.ac.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 *****************************/
+
+/*
+ * Setting IDETAPE_DEBUG to 1 will:
+ *
+ * 1. Generally log all driver actions.
+ * 2. Enable self-sanity checks in some places.
+ *
+ * Use IDETAPE_DEBUG when encountering a problem with the driver.
+ *
+ * Setting IDETAPE_DEBUG 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.
+ */
+
+#define IDETAPE_DEBUG 0
+
+/*
+ * 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 2
+
+/*
+ * In case the tape is not at the requested block, we re-position the
+ * tape. Repeat the procedure for IDETAPE_LOCATE_RETRIES times before
+ * we give up and abort the request. Note that this should not usually
+ * happen when using only the character device interface.
+ */
+
+#define IDETAPE_LOCATE_RETRIES 1
+
+/*
+ * 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. Hopefully. :-)
+ */
+
+#define IDETAPE_PC_STACK 10+\
+ IDETAPE_MAX_PC_RETRIES+\
+ 3*IDETAPE_LOCATE_RETRIES*IDETAPE_MAX_PC_RETRIES
+/*
+ * Media access packet command (like the LOCATE command) have immediate
+ * status with a delayed (and usually long) execution. The tape doesn't
+ * issue an interrupt when the command is actually complete (so that the
+ * bus is freed to use the other IDE device on the same interface), so we
+ * must for poll for this event.
+ *
+ * We set a timer with polling frequency of 1/IDETAPE_DSC_MEDIA_ACCESS_FREQUENCY
+ * in this case. We also poll for DSC *before* read/write commands. At
+ * this time the DSC role is changed and instead of signalling command
+ * completion, it will signal buffer availability. Since read/write
+ * commands are fast in comparision to media access commands, the polling
+ * frequency here should be much higher.
+ *
+ * We will insist of reading DSC=1 for IDETAPE_DSC_COUNT times in a row,
+ * to accommodate for random fluctuations in the sampling of DSC.
+ * We will also set IDETAPE_DSC_POLLING_FREQUENCY to a rather low
+ * frequency which besides freeing the CPU and the bus will let
+ * random fluctuations a time to settle down.
+ *
+ * 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.
+ *
+ * Once we pass a threshold, the polling frequency will change to
+ * a slow frequency: On relatively fast operations, there is a point
+ * in polling fast, but if we sense that the operation is taking too
+ * much time, we will poll at a lower frequency.
+ */
+
+#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_READ_WRITE_FREQUENCY HZ/20 /* 50 msec */
+#define IDETAPE_DSC_TIMEOUT 2*60*60*HZ /* 2 hours */
+#define IDETAPE_DSC_COUNT 1 /* Assume no DSC fluctuations */
+
+/*
+ * As explained in many places through the code, we provide both a block
+ * device and a character device interface to the tape. The block device
+ * interface is needed for compatibility with ide.c. The character device
+ * interface is the higher level of the driver, and passes requests
+ * to the lower part of the driver which interfaces with ide.c.
+ * Using the block device interface, we can bypass this high level
+ * of the driver, talking directly with the lower level part.
+ *
+ * It is intended that the character device interface will be used by
+ * the user. To prevent mistakes in this regard, opening of the block
+ * device interface will be refused if ALLOW_OPENING_BLOCK_DEVICE is 0.
+ *
+ * Do not change the following parameter unless you are developing
+ * the driver itself.
+ */
+
+#define IDETAPE_ALLOW_OPENING_BLOCK_DEVICE 0
+
+/*************************** End of tunable parameters ***********************/
+
+/*
+ * Definitions which are already needed in ide.h
+ */
+
+/*
+ * The following is currently not used.
+ */
+
+typedef enum {no_excess_data,excess_data_read,excess_data_write} excess_data_status_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; /* Set when an error occured */
+ byte active; /* Set when a packet command is in progress */
+ byte wait_for_dsc; /* 1 When polling for DSC */
+ byte dsc_count;
+ 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;
+
+/*
+ * 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 usually 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.
+ */
+
+ struct request *postponed_rq;
+ byte dsc_count;
+ unsigned long dsc_polling_start;
+ struct timer_list dsc_timer; /* Timer used to poll for dsc */
+ unsigned long dsc_polling_frequency;
+ unsigned long dsc_timeout; /* Maximum waiting time */
+ byte dsc_received;
+
+ /* 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) */
+ unsigned long locate_to; /* We want to reach this block, as a part */
+ /* of handling the current request */
+ byte locate_retries; /* Each time, increase locate_retries */
+
+ unsigned long last_written_block; /* Once writing started, we don't allow read */
+ byte last_written_valid; /* access beyond the last written block */
+ /* ??? Should I remove this ? */
+
+ /* Last error information */
+
+ byte sense_key,asc,ascq;
+
+ /* Character device operation */
+
+ unsigned char last_dt_was_write; /* Last character device data transfer was a write */
+ byte busy; /* Device already opened */
+
+ /* Device information */
+
+ unsigned short tape_block_size;
+ idetape_capabilities_page_t capabilities; /* Capabilities and Mechanical Page */
+
+ /* Data buffer */
+
+ char *data_buffer;
+
+} idetape_tape_t;
+
+#endif /* IDETAPE_H */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this