📄 ide-tape.c
字号:
char *b_data; int b_count; byte *buffer; /* Data buffer */ byte *current_position; /* Pointer into the above buffer */ ide_startstop_t (*callback) (ide_drive_t *); /* Called when this packet command is completed */ byte pc_buffer[IDETAPE_PC_BUFFER_SIZE]; /* Temporary buffer */ unsigned long flags; /* Status/Action bit flags: long for set_bit */} idetape_pc_t;/* * Packet command flag 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 *//* * Capabilities and Mechanical Status Page */typedef struct { unsigned page_code :6; /* Page code - Should be 0x2a */ __u8 reserved0_6 :1; __u8 ps :1; /* parameters saveable */ __u8 page_length; /* Page Length - Should be 0x12 */ __u8 reserved2, 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 */ __u8 disconnect :1; /* The device can break request > ctl */ __u8 reserved6_5 :1; 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 blk32768 :1; /* slowb - the device restricts the byte count for PIO */ /* transfers for slow buffer memory ??? */ /* Also 32768 block size in some cases */ __u16 max_speed; /* Maximum speed supported in KBps */ __u8 reserved10, reserved11; __u16 ctl; /* Continuous Transfer Limit in blocks */ __u16 speed; /* Current Speed, in KBps */ __u16 buffer_size; /* Buffer Size, in 512 bytes */ __u8 reserved18, reserved19;} idetape_capabilities_page_t;/* * Block Size Page */typedef struct { unsigned page_code :6; /* Page code - Should be 0x30 */ unsigned reserved1_6 :1; unsigned ps :1; __u8 page_length; /* Page Length - Should be 2 */ __u8 reserved2; unsigned play32 :1; unsigned play32_5 :1; unsigned reserved2_23 :2; unsigned record32 :1; unsigned record32_5 :1; unsigned reserved2_6 :1; unsigned one :1;} idetape_block_size_page_t;/* * A pipeline stage. */typedef struct idetape_stage_s { struct request rq; /* The corresponding request */ struct buffer_head *bh; /* The data buffers */ struct idetape_stage_s *next; /* Pointer to the next stage */ os_aux_t *aux; /* OnStream aux ptr */} idetape_stage_t;/* * REQUEST SENSE packet command result - Data Format. */typedef struct { unsigned error_code :7; /* Current of deferred errors */ unsigned valid :1; /* The information field conforms to QIC-157C */ __u8 reserved1 :8; /* Segment Number - Reserved */ unsigned sense_key :4; /* Sense Key */ unsigned reserved2_4 :1; /* Reserved */ unsigned ili :1; /* Incorrect Length Indicator */ unsigned eom :1; /* End Of Medium */ unsigned filemark :1; /* Filemark */ __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 */ unsigned sk_specific1 :7; /* Sense Key Specific */ unsigned sksv :1; /* Sense Key Specific information is valid */ __u8 sk_specific2; /* Sense Key Specific */ __u8 sk_specific3; /* Sense Key Specific */ __u8 pad[2]; /* Padding to 20 bytes */} idetape_request_sense_result_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 idetape_tape_t, defined below. */typedef struct { ide_drive_t *drive; devfs_handle_t de_r, de_n; /* * 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_pc_t *pc; /* Current packet command */ idetape_pc_t *failed_pc; /* Last failed packet command */ idetape_pc_t pc_stack[IDETAPE_PC_STACK];/* Packet command stack */ int pc_stack_index; /* Next free packet command storage space */ struct request rq_stack[IDETAPE_PC_STACK]; int rq_stack_index; /* We implement a circular array */ /* * DSC polling variables. * * 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 requests can be * queued in our internal pipeline, but they will be visible * to ide.c only one at a time. */ struct request *postponed_rq; 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 */ 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 */ /* * Read position information */ byte partition; unsigned int first_frame_position; /* Current block */ unsigned int last_frame_position; unsigned int blocks_in_buffer; /* * Last error information */ byte sense_key, asc, ascq; /* * Character device operation */ unsigned int minor; char name[4]; /* device name */ idetape_chrdev_direction_t chrdev_direction; /* Current character device data transfer direction */ /* * Device information */ unsigned short tape_block_size; /* Usually 512 or 1024 bytes */ int user_bs_factor; 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 */ int stage_size; /* Data buffer size (chosen based on the tape's recommendation */ idetape_stage_t *merge_stage; int merge_stage_size; struct buffer_head *bh; char *b_data; int b_count; /* * Pipeline parameters. * * To accomplish non-pipelined mode, we simply set the following * variables to zero (or NULL, where appropriate). */ int nr_stages; /* Number of currently used stages */ int nr_pending_stages; /* Number of pending stages */ int max_stages, min_pipeline, max_pipeline; /* We will not allocate more than this number of stages */ idetape_stage_t *first_stage; /* The first stage which will be removed from the pipeline */ idetape_stage_t *active_stage; /* The currently active stage */ idetape_stage_t *next_stage; /* Will be serviced after the currently active request */ idetape_stage_t *last_stage; /* New requests will be added to the pipeline here */ idetape_stage_t *cache_stage; /* Optional free stage which we can use */ int pages_per_stage; int excess_bh_size; /* Wasted space in each stage */ unsigned long flags; /* Status/Action flags: long for set_bit */ spinlock_t spinlock; /* protects the ide-tape queue */ /* * Measures average tape speed */ unsigned long avg_time; int avg_size; int avg_speed; idetape_request_sense_result_t sense; /* last sense information */ char vendor_id[10]; char product_id[18]; char firmware_revision[6]; int firmware_revision_num; int door_locked; /* the door is currently locked */ /* * OnStream flags */ int onstream; /* the tape is an OnStream tape */ int raw; /* OnStream raw access (32.5KB block size) */ int cur_frames; /* current number of frames in internal buffer */ int max_frames; /* max number of frames in internal buffer */ int logical_blk_num; /* logical block number */ __u16 wrt_pass_cntr; /* write pass counter */ __u32 update_frame_cntr; /* update frame counter */ struct completion *waiting; int onstream_write_error; /* write error recovery active */ int header_ok; /* header frame verified ok */ int linux_media; /* reading linux-specifc media */ int linux_media_version; char application_sig[5]; /* application signature */ int filemark_cnt; int first_mark_addr; int last_mark_addr; int eod_frame_addr; unsigned long cmd_start_time; unsigned long max_cmd_time; unsigned capacity; /* * Optimize the number of "buffer filling" * mode sense commands. */ unsigned long last_buffer_fill; /* last time in which we issued fill cmd */ int req_buffer_fill; /* buffer fill command requested */ int writes_since_buffer_fill; int reads_since_buffer_fill; /* * Limit the number of times a request can * be postponed, to avoid an infinite postpone * deadlock. */ int postpone_cnt; /* request postpone count limit */ /* * Measures number of frames: * * 1. written/read to/from the driver pipeline (pipeline_head). * 2. written/read to/from the tape buffers (buffer_head). * 3. written/read by the tape to/from the media (tape_head). */ int pipeline_head; int buffer_head; int tape_head; int last_tape_head; /* * Speed control at the tape buffers input/output */ unsigned long insert_time; int insert_size; int insert_speed; int max_insert_speed; int measure_insert_time; /* * Measure tape still time, in milliseconds */ unsigned long tape_still_time_begin; int tape_still_time; /* * Speed regulation negative feedback loop */ int speed_control; int pipeline_head_speed, controlled_pipeline_head_speed, uncontrolled_pipeline_head_speed; int controlled_last_pipeline_head, uncontrolled_last_pipeline_head; unsigned long uncontrolled_pipeline_head_time, controlled_pipeline_head_time; int controlled_previous_pipeline_head, uncontrolled_previous_pipeline_head; unsigned long controlled_previous_head_time, uncontrolled_previous_head_time; int restart_speed_control_req; /* * Debug_level determines amount of debugging output; * can be changed using /proc/ide/hdx/settings * 0 : almost no debugging output * 1 : 0+output errors only * 2 : 1+output all sensekey/asc * 3 : 2+follow all chrdev related procedures * 4 : 3+follow all procedures * 5 : 4+include pc_stack rq_stack info * 6 : 5+USE_COUNT updates */ int debug_level; } idetape_tape_t;/* * Tape door status */#define DOOR_UNLOCKED 0#define DOOR_LOCKED 1#define DOOR_EXPLICITLY_LOCKED 2/* * Tape flag bits values. */#define IDETAPE_IGNORE_DSC 0#define IDETAPE_ADDRESS_VALID 1 /* 0 When the tape position is unknown */#define IDETAPE_BUSY 2 /* Device already opened */#define IDETAPE_PIPELINE_ERROR 3 /* Error detected in a pipeline stage */#define IDETAPE_DETECT_BS 4 /* Attempt to auto-detect the current user block size */#define IDETAPE_FILEMARK 5 /* Currently on a filemark */#define IDETAPE_DRQ_INTERRUPT 6 /* DRQ interrupt device */#define IDETAPE_READ_ERROR 7#define IDETAPE_PIPELINE_ACTIVE 8 /* pipeline active *//* * Supported ATAPI tape drives packet commands */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -