patch-1.3.54 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: 241
- Date:
Thu Jan 4 07:43:40 1996
- Orig file:
v1.3.53/linux/drivers/block/ide-tape.h
- Orig date:
Sun Dec 17 11:43:12 1995
diff -u --recursive --new-file v1.3.53/linux/drivers/block/ide-tape.h linux/drivers/block/ide-tape.h
@@ -1,7 +1,7 @@
/*
- * linux/drivers/block/ide-tape.h Version 1.1 - ALPHA Dec 14, 1995
+ * linux/drivers/block/ide-tape.h Version 1.2 - ALPHA Jan 1, 1996
*
- * Copyright (C) 1995 Gadi Oxman <tgud@tochnapc2.technion.ac.il>
+ * Copyright (C) 1995, 1996 Gadi Oxman <tgud@tochnapc2.technion.ac.il>
*/
/*
@@ -23,8 +23,7 @@
*
* 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. Currently, pipelined
- * mode is supported only on writes.
+ * 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
@@ -32,9 +31,8 @@
* user program will then have enough time to prepare the next blocks
* while the tape is still busy working on the previous requests.
*
- * Pipelined (write) operation mode is enabled by default, but since
- * it has a few downfalls as well (Use of additional memory and deferred
- * error code to the application), you may wish to disable it.
+ * 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 .
*/
@@ -58,6 +56,29 @@
#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
@@ -76,21 +97,25 @@
#endif
/*
- * Setting IDETAPE_DEBUG to 1 will:
- *
- * 1. Generally log all driver actions.
- * 2. Enable self-sanity checks in some places.
+ * The following are used to debug the driver:
*
- * Use IDETAPE_DEBUG when encountering a problem with 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 IDETAPE_DEBUG to 0 will restore normal operation mode:
+ * 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 0
+#define IDETAPE_DEBUG_LOG 0
+#define IDETAPE_DEBUG_BUGS 1
/*
* After each failed packet command we issue a request sense command
@@ -147,9 +172,12 @@
* request queue, so that ide.c will service requests from
* the other device on the same interface meanwhile.
*
- * The polling frequency is 1/IDETAPE_DSC_READ_WRITE_FREQUENCY,
- * and it should be relatively fast. The default is a period
- * of 50 msec.
+ * 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
@@ -173,7 +201,30 @@
*
*/
-#define IDETAPE_DSC_READ_WRITE_FREQUENCY 5*HZ/100 /* 50 msec */
+/*
+ * 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 */
@@ -184,14 +235,13 @@
/*
* Definitions which are already needed in ide.h
*/
-
+
/*
- * The following is currently not used.
+ * Current character device data transfer direction.
*/
+
+typedef enum {idetape_direction_none,idetape_direction_read,idetape_direction_write} chrdev_direction_t;
-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 *);
@@ -203,10 +253,9 @@
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;
+ 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 */
unsigned long request_transfer; /* Bytes to transfer */
unsigned long actually_transferred; /* Bytes actually transferred */
unsigned long buffer_size; /* Size of our data buffer */
@@ -353,12 +402,20 @@
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 request_dsc_callback;
byte last_status; /* Contents of the tape status register */
/* before the current request (saved for us */
/* by ide.c) */
@@ -374,7 +431,7 @@
/* Character device operation */
- unsigned char last_dt_was_write; /* Last character device data transfer was a write */
+ chrdev_direction_t chrdev_direction; /* Current character device data transfer direction */
byte busy; /* Device already opened */
/* Device information */
@@ -410,24 +467,25 @@
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; /* Will be serviced after the currently active request */
- idetape_pipeline_stage_t *last_stage; /* New write requests will be added to the pipeline here */
- int pipeline_was_full_once; /* Set at the first time we fill the pipeline since the tape was opened */
+ 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 */
- int pipeline_locked; /* Against race conditions ... */
} 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) { \
OUT_BYTE(hwif->tape_drive->select.all,IDE_SELECT_REG); \
hwif->tape_drive->tape.last_status=GET_STAT(); \
hwif->tape_drive->tape.request_status=0; \
- } \
- if (hwif->tape_drive->tape.request_dsc_callback) { \
- hwif->tape_drive->tape.request_dsc_callback=0; \
- idetape_put_back_postponed_request(hwif->tape_drive); \
} \
}
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