📄 osst.c
字号:
return (-EIO); } if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { printk(KERN_INFO "osst%i: Expected to find marker at block %d, not found\n", dev, next_mark_ppos); return (-EIO); } } } if (mt_op == MTFSF) STp->logical_blk_num++; STp->logical_blk_in_buffer = 0; return 0;}/* * In debug mode, we want to see as many errors as possible * to test the error recovery mechanism. */#if DEBUGstatic void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int retries){ unsigned char cmd[MAX_COMMAND_SIZE]; Scsi_Request * SRpnt = * aSRpnt; int dev = TAPE_NR(STp->devt); memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SELECT; cmd[1] = 0x10; cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH; (STp->buffer)->b_data[0] = cmd[4] - 1; (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */ (STp->buffer)->b_data[2] = 0; /* Reserved */ (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */ (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7); (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2; (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4; (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries; if (debugging) printk(OSST_DEB_MSG "osst%i: Setting number of retries on OnStream tape to %d\n", dev, retries); SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result) printk (KERN_ERR "osst%d: Couldn't set retries to %d\n", dev, retries);}#endif#if 0static void osst_update_markers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int last_mark_ppos, int this_mark_ppos){ int dev = TAPE_NR(STp->devt); int frame, reslt; if (STp->raw) return; STp->last_mark_ppos = this_mark_ppos; if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX) STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos); if (STp->filemark_cnt++ == 0) STp->first_mark_ppos = this_mark_ppos; if (STp->linux_media_version >= 4) return; if (last_mark_ppos == -1) return; STp->write_type = OS_WRITE_LAST_MARK; frame = osst_get_frame_position(STp, aSRpnt);#if DEBUG printk(OSST_DEB_MSG "osst%i: Update last_marker at frame %d\n", dev, last_mark_addr); printk(OSST_DEB_MSG "osst%i: current position %d, lblk %d, tape blk %d\n", dev, frame, STp->logical_blk_num, STp->last_frame_position);#endif osst_set_frame_position(STp, aSRpnt, last_mark_ppos, 0); osst_initiate_read (STp, aSRpnt); reslt = osst_read_block(STp, aSRpnt, 180); if (reslt) { printk(KERN_WARNING "osst%i: couldn't read last marker\n", dev); osst_set_frame_position(STp, aSRpnt, frame, 0); return; } if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { printk(KERN_WARNING "osst%i: expected marker at addr %d\n", dev, last_mark_ppos); osst_set_frame_position(STp, aSRpnt, frame, 0); return; }#if DEBUG printk(OSST_DEB_MSG "osst%i: writing back marker\n", dev);#endif STp->buffer->aux->next_mark_ppos = htonl(this_mark_ppos); osst_set_frame_position(STp, aSRpnt, last_mark_ppos, 0); STp->dirty = 1; if (osst_flush_write_buffer(STp, aSRpnt, 0) || osst_flush_drive_buffer(STp, aSRpnt) ) { printk(KERN_WARNING "osst%i: couldn't write marker back at addr %d\n", dev, last_mark_ppos); } osst_set_frame_position(STp, aSRpnt, frame, 0); return; /* FIXME -- errors should go back to user space */}#endifstatic int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt){ int result; int this_mark_ppos;#if DEBUG int dev = TAPE_NR(STp->devt);#endif if (STp->raw) return 0; STp->write_type = OS_WRITE_NEW_MARK; this_mark_ppos = osst_get_frame_position(STp, aSRpnt);#if DEBUG printk(OSST_DEB_MSG "osst%i: Writing Filemark %i at frame %d (lblk %d)\n", dev, STp->filemark_cnt, this_mark_ppos, STp->logical_blk_num);#endif osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->logical_blk_num++); STp->ps[STp->partition].rw = ST_WRITING; STp->dirty = 1; result = osst_flush_write_buffer(STp, aSRpnt, 0); result |= osst_flush_drive_buffer(STp, aSRpnt); STp->last_mark_ppos = this_mark_ppos; if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX) STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos); if (STp->filemark_cnt++ == 0) STp->first_mark_ppos = this_mark_ppos;// osst_update_markers(STp, aSRpnt, STp->last_mark_addr, this_mark_addr); return result;}static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt){ int result;#if DEBUG int dev = TAPE_NR(STp->devt);#endif if (STp->raw) return 0; STp->write_type = OS_WRITE_EOD; STp->eod_frame_ppos = osst_get_frame_position(STp, aSRpnt);#if DEBUG printk(OSST_DEB_MSG "osst%i: Writing EOD at %d=>%d\n", dev, STp->logical_blk_num, STp->eod_frame_ppos);#endif osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->logical_blk_num++); STp->ps[STp->partition].rw = ST_WRITING; STp->dirty = 1; result = osst_flush_write_buffer(STp, aSRpnt, 0); result |= osst_flush_drive_buffer(STp, aSRpnt); STp->eod_frame_lfa = --(STp->logical_blk_num); return result;}static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int block, int count){ int dev = TAPE_NR(STp->devt);#if DEBUG printk(OSST_DEB_MSG "osst%i: Reached onstream write filler group %d\n", dev, block);#endif osst_wait_ready(STp, aSRpnt, 60 * 5); osst_set_frame_position(STp, aSRpnt, block, 0); STp->write_type = OS_WRITE_FILLER; osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0); while (count--) { memcpy(STp->buffer->b_data, "Filler", 6); STp->buffer->buffer_bytes = 6; STp->dirty = 1; if (osst_flush_write_buffer(STp, aSRpnt, 0)) { printk(KERN_INFO "osst%i: Couldn't write filler frame\n", dev); return (-EIO); } }#if DEBUG printk(OSST_DEB_MSG "osst%i: Exiting onstream write filler group\n", dev);#endif return osst_flush_drive_buffer(STp, aSRpnt);}static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int block, int count){ int dev = TAPE_NR(STp->devt); int result;#if DEBUG printk(OSST_DEB_MSG "osst%i: Reached onstream write header group %d\n", dev, block);#endif osst_wait_ready(STp, aSRpnt, 60 * 5); osst_set_frame_position(STp, aSRpnt, block, 0); STp->write_type = OS_WRITE_HEADER; STp->ps[STp->partition].rw = ST_WRITING; osst_init_aux(STp, OS_FRAME_TYPE_HEADER, STp->logical_blk_num); while (count--) { osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache); STp->buffer->buffer_bytes = sizeof(os_header_t); STp->dirty = 1; if (osst_flush_write_buffer(STp, aSRpnt, 0)) { printk(KERN_INFO "osst%i: Couldn't write header frame\n", dev); return (-EIO); } } result = osst_flush_drive_buffer(STp, aSRpnt);#if DEBUG printk(OSST_DEB_MSG "osst%i: Write onstream header group %s\n", dev, result?"failed":"done");#endif return result;}static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int locate_eod){ os_header_t * header; int result; int dev = TAPE_NR(STp->devt);#if DEBUG printk(OSST_DEB_MSG "osst%i: Writing tape header\n", dev);#endif if (STp->raw) return 0; if (STp->header_cache == NULL) { if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) { printk(KERN_ERR "osst%i: Failed to allocate header cache\n", dev); return (-ENOMEM); } memset(STp->header_cache, 0, sizeof(os_header_t));#if DEBUG printk(OSST_DEB_MSG "osst%d: Allocated and cleared memory for header cache\n", dev);#endif } if (STp->header_ok) STp->update_frame_cntr++; else STp->update_frame_cntr = 0; header = STp->header_cache; strcpy(header->ident_str, "ADR_SEQ"); header->major_rev = 1; header->minor_rev = 4; header->ext_trk_tb_off = htons(17192); header->pt_par_num = 1; header->partition[0].partition_num = OS_DATA_PARTITION; header->partition[0].par_desc_ver = OS_PARTITION_VERSION; header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr); header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos); header->partition[0].last_frame_ppos = htonl(STp->capacity); header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos); header->cfg_col_width = htonl(20); header->dat_col_width = htonl(1500); header->qfa_col_width = htonl(0); header->ext_track_tb.nr_stream_part = 1; header->ext_track_tb.et_ent_sz = 32; header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0; header->ext_track_tb.dat_ext_trk_ey.fmt = 1; header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736); header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0; header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa); header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos); header->dat_fm_tab.fm_part_num = 0; header->dat_fm_tab.fm_tab_ent_sz = 4; header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX? STp->filemark_cnt:OS_FM_TAB_MAX); result = __osst_write_header(STp, aSRpnt, 0xbae, 5); if (STp->update_frame_cntr == 0) osst_write_filler(STp, aSRpnt, 0xbb3, 5); result &= __osst_write_header(STp, aSRpnt, 5, 5); if (locate_eod) {#if DEBUG printk(OSST_DEB_MSG "osst%i: locating back to eod frame addr %d\n", dev, STp->eod_frame_ppos);#endif osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0); } if (result) printk(KERN_WARNING "osst%i: write header failed\n", dev); else { memcpy(STp->application_sig, "LIN4", 4); STp->linux_media = 1; STp->linux_media_version = 4; STp->header_ok = 1; } return result;}static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt){ if (STp->header_cache != NULL) memset(STp->header_cache, 0, sizeof(os_header_t)); STp->logical_blk_num = 0; STp->logical_blk_in_buffer = 0; STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A; STp->filemark_cnt = 0; STp->first_mark_ppos = STp->last_mark_ppos = -1; return osst_write_header(STp, aSRpnt, 1);}static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int block){ int dev = TAPE_NR(STp->devt); os_header_t * header; os_aux_t * aux; char id_string[8]; int linux_media_version, update_frame_cntr; if (STp->raw) return 1; if (block == 5 || block == 0xbae || STp->buffer->syscall_result) { if (osst_set_frame_position(STp, aSRpnt, block, 0)) printk(KERN_WARNING "osst%i: Couldn't position tape\n", dev); if (osst_initiate_read (STp, aSRpnt)) { printk(KERN_WARNING "osst%i: Couldn't initiate read\n", dev); return 0; } } if (osst_read_block(STp, aSRpnt, 180)) {#if DEBUG printk(OSST_DEB_MSG "osst%i: Couldn't read header frame\n", dev);#endif return 0; } header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */ aux = STp->buffer->aux; if (aux->frame_type != OS_FRAME_TYPE_HEADER) {#if DEBUG printk(OSST_DEB_MSG "osst%i: Skipping non-header frame (%d)\n", dev, block);#endif return 0; } if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 && strncmp(header->ident_str, "ADR-SEQ", 7) != 0) { strncpy(id_string, header->ident_str, 7); id_string[7] = 0; printk(KERN_INFO "osst%i: Invalid header identification string %s\n", dev, id_string); return 0; } update_frame_cntr = ntohl(aux->update_frame_cntr); if (update_frame_cntr < STp->update_frame_cntr) {#if DEBUG printk(OSST_DEB_MSG "osst%i: Skipping frame %d with update_frame_counter %d<%d\n", dev, block, update_frame_cntr, STp->update_frame_cntr);#endif return 0; } if (header->major_rev != 1 || header->minor_rev != 4 ) { printk(KERN_INFO "osst%i: %s revision %d.%d detected (1.4 supported)\n", dev, (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4 )? "Invalid" : "Warning:", header->major_rev, header->minor_rev); if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4) return 0; } if (header->pt_par_num != 1) printk(KERN_INFO "osst%i: Warning: %d partitions defined, only one supported\n", dev, header->pt_par_num); memcpy(id_string, aux->application_sig, 4); id_string[4] = 0; if (memcmp(id_string, "LIN", 3) == 0) { STp->linux_media = 1; linux_media_version = id_string[3] - '0'; if (linux_media_version != 4) printk(KERN_INFO "osst%i: Linux media version %d detected (current 4)\n", dev, linux_media_version); } else { printk(KERN_WARNING "osst%i: non Linux media detected (%s)\n", dev, id_string); return 0; } if (linux_media_version < STp->linux_media_version) {#if DEBUG printk(OSST_DEB_MSG "osst%i: Skipping frame %d with linux_media_version %d\n", dev, block, linux_media_version);#endif return 0; } if (linux_media_version > STp->linux_media_version) {#if DEBUG printk(OSST_DEB_MSG "osst%i: Frame %d sets linux_media_version to %d\n", dev, block, linux_media_version);#endif memcpy(STp->application_sig, id_string, 5); STp->linux_media_version = linux_media_version; STp->update_frame_cntr = -1; } if (update_frame_cntr > STp->update_frame_cntr) {#if DEBUG printk(OSST_DEB_MSG "osst%i: Frame %d sets update_frame_counter to %d\n", dev, block, update_frame_cntr);#endif if (STp->header_cache == NULL) { if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) ==
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -