📄 osst.c
字号:
#if DEBUG if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted) { printk (OSST_DEB_MSG "osst%d:D: Wait for frame %i (>%i): %i-%i %i (%i)\n", dev, curr, curr+minlast, STp->first_frame_position, STp->last_frame_position, STp->cur_frames, result); notyetprinted--; }#endif set_current_state(TASK_INTERRUPTIBLE); schedule_timeout (HZ / OSST_POLL_PER_SEC); }#if DEBUG printk (OSST_DEB_MSG "osst%d:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n", dev, curr, curr+minlast, STp->first_frame_position, STp->last_frame_position, STp->cur_frames, (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);#endif return -EBUSY;}/* * Read the next OnStream tape frame at the current location */static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout){ unsigned char cmd[MAX_COMMAND_SIZE]; Scsi_Request * SRpnt; int retval = 0;#if DEBUG os_aux_t * aux = STp->buffer->aux; int dev = TAPE_NR(STp->devt);#endif /* TODO: Error handling */ if (STp->poll) retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout);#if 0// DEBUG printk ("osst_read: wait for frame returned %i\n", retval);#endif memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = READ_6; cmd[1] = 1; cmd[4] = 1;#if DEBUG if (debugging) printk(OSST_DEB_MSG "osst%d:D: Reading frame from OnStream tape\n", dev);#endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); if ((STp->buffer)->syscall_result) { retval = 1; if (STp->read_error_frame == 0) { STp->read_error_frame = STp->first_frame_position;#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Recording read error at %d\n", dev, STp->read_error_frame);#endif }#if DEBUG if (debugging) printk(OSST_DEB_MSG "osst%d:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", dev, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1], SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3], SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5], SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]);#endif } else STp->first_frame_position++;#if DEBUG if (debugging) { printk(OSST_DEB_MSG "osst%d:D: AUX: %c%c%c%c UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", dev, aux->application_sig[0], aux->application_sig[1], aux->application_sig[2], aux->application_sig[3], ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr), aux->frame_type==1?"EOD":aux->frame_type==2?"MARK": aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) ); if (aux->frame_type==2) printk(OSST_DEB_MSG "osst%d:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", dev, ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn)); printk(OSST_DEB_MSG "osst%d:D: Exit read frame from OnStream tape with code %d\n", dev, retval); }#endif return (retval);}static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt){ ST_partstat * STps = &(STp->ps[STp->partition]); Scsi_Request * SRpnt ; unsigned char cmd[MAX_COMMAND_SIZE]; int retval = 0;#if DEBUG int dev = TAPE_NR(STp->devt);#endif if (STps->rw != ST_READING) { /* Initialize read operation */ if (STps->rw == ST_WRITING) { osst_flush_write_buffer(STp, aSRpnt); osst_flush_drive_buffer(STp, aSRpnt); } STps->rw = ST_READING; STp->frame_in_buffer = 0; /* * Issue a read 0 command to get the OnStream drive * read frames into its buffer. */ memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = READ_6; cmd[1] = 1;#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Start Read Ahead on OnStream tape\n", dev);#endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; retval = STp->buffer->syscall_result; } return retval;}static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet){ ST_partstat * STps = &(STp->ps[STp->partition]); int dev = TAPE_NR(STp->devt); int cnt = 0, bad = 0, past = 0, x, position; /* * Search and wait for the next logical tape frame */ while (1) { if (cnt++ > 400) { printk(KERN_ERR "osst%d:E: Couldn't find logical frame %d, aborting\n", dev, frame_seq_number); if (STp->read_error_frame) { osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Repositioning tape to bad frame %d\n", dev, STp->read_error_frame);#endif STp->read_error_frame = 0; } return (-EIO); }#if DEBUG if (debugging) printk(OSST_DEB_MSG "osst%d:D: Looking for frame %d, attempt %d\n", dev, frame_seq_number, cnt);#endif if ( osst_initiate_read(STp, aSRpnt) || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) { if (STp->raw) return (-EIO); position = osst_get_frame_position(STp, aSRpnt); if (position >= 0xbae && position < 0xbb8) position = 0xbb8; else if (position > STp->eod_frame_ppos || ++bad == 10) { position = STp->read_error_frame - 1; } else { position += 39; cnt += 20; }#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Bad frame detected, positioning tape to block %d\n", dev, position);#endif osst_set_frame_position(STp, aSRpnt, position, 0); continue; } if (osst_verify_frame(STp, frame_seq_number, quiet)) break; if (osst_verify_frame(STp, -1, quiet)) { x = ntohl(STp->buffer->aux->frame_seq_num); if (STp->fast_open) { printk(KERN_WARNING "osst%d:W: Found logical frame %d instead of %d after fast open\n", dev, x, frame_seq_number); STp->header_ok = 0; STp->read_error_frame = 0; return (-EIO); } if (x > frame_seq_number) { if (++past > 3) { /* positioning backwards did not bring us to the desired frame */ position = STp->read_error_frame - 1; } else { position = osst_get_frame_position(STp, aSRpnt) + frame_seq_number - x - 1; if (STp->first_frame_position >= 3000 && position < 3000) position -= 10; }#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Found logical frame %d while looking for %d: back up %d\n", dev, x, frame_seq_number, STp->first_frame_position - position);#endif osst_set_frame_position(STp, aSRpnt, position, 0); cnt += 10; } else past = 0; } if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Skipping config partition\n", dev);#endif osst_set_frame_position(STp, aSRpnt, 0xbb8, 0); cnt--; } STp->frame_in_buffer = 0; } if (cnt > 1) { STp->recover_count++; STp->recover_erreg++; printk(KERN_WARNING "osst%d:I: Don't worry, Read error at position %d recovered\n", dev, STp->read_error_frame); } STp->read_count++;#if DEBUG if (debugging || STps->eof) printk(OSST_DEB_MSG "osst%d:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n", dev, frame_seq_number, STp->frame_seq_number, STps->eof);#endif STp->fast_open = FALSE; STp->read_error_frame = 0; return (STps->eof);}static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num){ ST_partstat * STps = &(STp->ps[STp->partition]); int dev = TAPE_NR(STp->devt); int retries = 0; int frame_seq_estimate, ppos_estimate, move; if (logical_blk_num < 0) logical_blk_num = 0;#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Seeking logical block %d (now at %d, size %d%c)\n", dev, logical_blk_num, STp->logical_blk_num, STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');#endif /* Do we know where we are? */ if (STps->drv_block >= 0) { move = logical_blk_num - STp->logical_blk_num; if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; move /= (OS_DATA_SIZE / STp->block_size); frame_seq_estimate = STp->frame_seq_number + move; } else frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE; if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10; else ppos_estimate = frame_seq_estimate + 20; while (++retries < 10) { if (ppos_estimate > STp->eod_frame_ppos-2) { frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate; ppos_estimate = STp->eod_frame_ppos - 2; } if (frame_seq_estimate < 0) { frame_seq_estimate = 0; ppos_estimate = 10; } osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0); if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) { /* we've located the estimated frame, now does it have our block? */ if (logical_blk_num < STp->logical_blk_num || logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) { if (STps->eof == ST_FM_HIT) move = logical_blk_num < STp->logical_blk_num? -2 : 1; else { move = logical_blk_num - STp->logical_blk_num; if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; move /= (OS_DATA_SIZE / STp->block_size); }#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n", dev, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, STp->logical_blk_num, logical_blk_num, move);#endif frame_seq_estimate += move; ppos_estimate += move; continue; } else { STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size; STp->buffer->buffer_bytes -= STp->buffer->read_pointer; STp->logical_blk_num = logical_blk_num;#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n", dev, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, STp->block_size);#endif STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); if (STps->eof == ST_FM_HIT) { STps->drv_file++; STps->drv_block = 0; } else { STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? STp->logical_blk_num - (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): -1; } STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; return 0; } } if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0) goto error; /* we are not yet at the estimated frame, adjust our estimate of its physical position */#if DEBUG printk(OSST_DEB_MSG "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", dev, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, STp->logical_blk_num, logical_blk_num);#endif if (frame_seq_estimate != STp->frame_seq_number) ppos_estimate += frame_seq_estimate - STp->frame_seq_number; else break; }error: printk(KERN_ERR "osst%d:E: Couldn't seek to logical block %d (at %d), %d retries\n", dev, logical_blk_num, STp->logical_blk_num, retries); return (-EIO);}/* The values below are based on the OnStream frame payload size of 32K == 2**15, * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1. */#define OSST_FRAME_SHIFT 6#define OSST_SECTOR_SHIFT 9#define OSST_SECTOR_MASK 0x03Fstatic int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt){ int sector;#if DEBUG int dev = TAPE_NR(STp->devt); printk(OSST_DEB_MSG "osst%d:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n", dev, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, STp->ps[STp->partition].rw == ST_WRITING?'w':'r', STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes: STp->buffer->read_pointer, STp->ps[STp->partition].eof);#endif /* do we know where we are inside a file? */ if (STp->ps[STp->partition].drv_block >= 0) { sector = (STp->frame_in_buffer ? STp->first_frame_position-1 : STp->first_frame_position) << OSST_FRAME_SHIFT; if (STp->ps[STp->partition].rw == ST_WRITING) sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; else sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; } else { sector = osst_get_frame_position(STp, aSRpnt); if (sector > 0) sector <<= OSST_FRAME_SHIFT; } return sector;}static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sector){ ST_partstat * STps = &(STp->ps[STp->partition]); int frame = sector >> OSST_FRAME_SHIFT, offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, r;#if DEBUG int dev = TAPE_NR(STp->devt); printk(OSST_DEB_MSG "osst%d:D: Seeking sector %d in frame %d at offset %d\n", dev, sector, frame, offset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -