URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [block/] [ide-tape.h] - Rev 1777
Go to most recent revision | Compare with Previous | Blame | View Log
/* * linux/drivers/block/ide-tape.h Version 1.9 - ALPHA Nov 5, 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 20 /* * 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 /* * The following parameter is used to select the point in the internal * tape fifo in which we will start to refill the buffer. Decreasing * the following parameter will improve the system's latency and * interactive response, while using a high value might improve sytem * throughput. */ #define IDETAPE_FIFO_THRESHOLD 2 /* * DSC timings. */ #define IDETAPE_DSC_READ_WRITE_FALLBACK_FREQUENCY 5*HZ/100 /* 50 msec */ #define IDETAPE_DSC_READ_WRITE_LOWEST_FREQUENCY 40*HZ/100 /* 400 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 */ int filemark; /* Currently on a filemark */ 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 */ int drq_interrupt; } 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 */
Go to most recent revision | Compare with Previous | Blame | View Log