Lines Matching +full:frame +full:- +full:buffer
16 Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
21 Microscopic alterations - Rik Ling, 2000/12/21
23 Some small formal changes - aeb, 950809
32 …D_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
60 is defined and non-zero. */
90 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
118 /* The buffer size should fit into the 24 bits for length in the
119 6-byte SCSI read and write commands. */
120 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
121 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
143 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
187 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame,…
197 return tape->drive->disk_name; in tape_name()
200 /* Routines that handle the interaction with mid-layer SCSI routines */
207 const u8 *sense = SRpnt->sense; in osst_analyze_sense()
209 s->have_sense = scsi_normalize_sense(SRpnt->sense, in osst_analyze_sense()
210 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr); in osst_analyze_sense()
211 s->flags = 0; in osst_analyze_sense()
213 if (s->have_sense) { in osst_analyze_sense()
214 s->deferred = 0; in osst_analyze_sense()
215 s->remainder_valid = in osst_analyze_sense()
216 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64); in osst_analyze_sense()
219 s->deferred = 1; in osst_analyze_sense()
221 s->fixed_format = 1; in osst_analyze_sense()
222 s->flags = sense[2] & 0xe0; in osst_analyze_sense()
225 s->deferred = 1; in osst_analyze_sense()
227 s->fixed_format = 0; in osst_analyze_sense()
229 s->flags = ucp ? (ucp[3] & 0xe0) : 0; in osst_analyze_sense()
239 int result = SRpnt->result; in osst_chk_result()
240 u8 * sense = SRpnt->sense, scode; in osst_chk_result()
249 cmdstatp = &STp->buffer->cmdstat; in osst_chk_result()
252 if (cmdstatp->have_sense) in osst_chk_result()
253 scode = STp->buffer->cmdstat.sense_hdr.sense_key; in osst_chk_result()
260 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], in osst_chk_result()
261 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); in osst_chk_result()
264 if (cmdstatp->have_sense) in osst_chk_result()
265 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); in osst_chk_result()
269 if (cmdstatp->have_sense && ( in osst_chk_result()
275 SRpnt->cmd[0] != MODE_SENSE && in osst_chk_result()
276 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ in osst_chk_result()
277 if (cmdstatp->have_sense) { in osst_chk_result()
279 __scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); in osst_chk_result()
297 STp->pos_unknown |= STp->device->was_reset; in osst_chk_result()
299 if (cmdstatp->have_sense && scode == RECOVERED_ERROR) { in osst_chk_result()
300 STp->recover_count++; in osst_chk_result()
301 STp->recover_erreg++; in osst_chk_result()
304 if (SRpnt->cmd[0] == READ_6) in osst_chk_result()
306 else if (SRpnt->cmd[0] == WRITE_6) in osst_chk_result()
311 STp->recover_count); in osst_chk_result()
317 return (-EIO); in osst_chk_result()
324 struct osst_request *SRpnt = req->end_io_data; in osst_end_async()
325 struct osst_tape *STp = SRpnt->stp; in osst_end_async()
326 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; in osst_end_async()
328 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; in osst_end_async()
330 STp->write_pending = 0; in osst_end_async()
332 if (SRpnt->waiting) in osst_end_async()
333 complete(SRpnt->waiting); in osst_end_async()
335 if (SRpnt->bio) { in osst_end_async()
336 kfree(mdata->pages); in osst_end_async()
337 blk_rq_unmap_user(SRpnt->bio); in osst_end_async()
340 __blk_put_request(req->q, req); in osst_end_async()
355 int cmd_len, int data_direction, void *buffer, unsigned bufflen, in osst_execute() argument
360 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; in osst_execute()
365 req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL); in osst_execute()
369 req->cmd_type = REQ_TYPE_BLOCK_PC; in osst_execute()
370 req->cmd_flags |= REQ_QUIET; in osst_execute()
372 SRpnt->bio = NULL; in osst_execute()
375 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer; in osst_execute()
385 mdata->null_mapped = 1; in osst_execute()
387 mdata->page_order = get_order(sgl[0].length); in osst_execute()
388 mdata->nr_entries = in osst_execute()
389 DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order); in osst_execute()
390 mdata->offset = 0; in osst_execute()
392 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL); in osst_execute()
397 SRpnt->bio = req->bio; in osst_execute()
398 mdata->pages = pages; in osst_execute()
401 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL); in osst_execute()
406 req->cmd_len = cmd_len; in osst_execute()
407 memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ in osst_execute()
408 memcpy(req->cmd, cmd, req->cmd_len); in osst_execute()
409 req->sense = SRpnt->sense; in osst_execute()
410 req->sense_len = 0; in osst_execute()
411 req->timeout = timeout; in osst_execute()
412 req->retries = retries; in osst_execute()
413 req->end_io_data = SRpnt; in osst_execute()
415 blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async); in osst_execute()
437 if (!do_wait && ((STp->buffer)->last_SRpnt)) { in osst_do_scsi()
441 (STp->buffer)->syscall_result = (-EINTR); in osst_do_scsi()
443 (STp->buffer)->syscall_result = (-EBUSY); in osst_do_scsi()
453 (STp->buffer)->syscall_result = (-EINTR); in osst_do_scsi()
455 (STp->buffer)->syscall_result = (-EBUSY); in osst_do_scsi()
458 SRpnt->stp = STp; in osst_do_scsi()
464 (STp->buffer)->last_SRpnt = SRpnt; in osst_do_scsi()
466 waiting = &STp->wait; in osst_do_scsi()
468 SRpnt->waiting = waiting; in osst_do_scsi()
470 use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0; in osst_do_scsi()
472 bp = (char *)&(STp->buffer->sg[0]); in osst_do_scsi()
473 if (STp->buffer->sg_segs < use_sg) in osst_do_scsi()
474 use_sg = STp->buffer->sg_segs; in osst_do_scsi()
477 bp = (STp->buffer)->b_data; in osst_do_scsi()
479 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); in osst_do_scsi()
480 STp->buffer->cmdstat.have_sense = 0; in osst_do_scsi()
481 STp->buffer->syscall_result = 0; in osst_do_scsi()
485 /* could not allocate the buffer or request was too large */ in osst_do_scsi()
486 (STp->buffer)->syscall_result = (-EBUSY); in osst_do_scsi()
489 SRpnt->waiting = NULL; in osst_do_scsi()
490 STp->buffer->syscall_result = osst_chk_result(STp, SRpnt); in osst_do_scsi()
492 if (STp->buffer->syscall_result == 0 && in osst_do_scsi()
496 (STp->first_frame_position == 240 in osst_do_scsi()
497 /* or STp->read_error_frame to fail again on the block calculated above */ && in osst_do_scsi()
500 STp->buffer->last_result_fatal = 1; in osst_do_scsi()
508 /* Handle the write-behind checking (downs the semaphore) */
513 STbuffer = STp->buffer; in osst_write_behind_check()
516 if (STp->write_pending) in osst_write_behind_check()
517 STp->nbr_waits++; in osst_write_behind_check()
519 STp->nbr_finished++; in osst_write_behind_check()
521 wait_for_completion(&(STp->wait)); in osst_write_behind_check()
522 STp->buffer->last_SRpnt->waiting = NULL; in osst_write_behind_check()
524 STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt); in osst_write_behind_check()
526 if (STp->buffer->syscall_result) in osst_write_behind_check()
527 STp->buffer->syscall_result = in osst_write_behind_check()
528 osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1); in osst_write_behind_check()
530 STp->first_frame_position++; in osst_write_behind_check()
532 osst_release_request(STp->buffer->last_SRpnt); in osst_write_behind_check()
534 if (STbuffer->writing < STbuffer->buffer_bytes) in osst_write_behind_check()
535 printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n"); in osst_write_behind_check()
537 STbuffer->last_SRpnt = NULL; in osst_write_behind_check()
538 STbuffer->buffer_bytes -= STbuffer->writing; in osst_write_behind_check()
539 STbuffer->writing = 0; in osst_write_behind_check()
553 os_aux_t *aux = STp->buffer->aux; in osst_init_aux()
554 os_partition_t *par = &aux->partition; in osst_init_aux()
555 os_dat_t *dat = &aux->dat; in osst_init_aux()
557 if (STp->raw) return; in osst_init_aux()
560 aux->format_id = htonl(0); in osst_init_aux()
561 memcpy(aux->application_sig, "LIN4", 4); in osst_init_aux()
562 aux->hdwr = htonl(0); in osst_init_aux()
563 aux->frame_type = frame_type; in osst_init_aux()
567 aux->update_frame_cntr = htonl(STp->update_frame_cntr); in osst_init_aux()
568 par->partition_num = OS_CONFIG_PARTITION; in osst_init_aux()
569 par->par_desc_ver = OS_PARTITION_VERSION; in osst_init_aux()
570 par->wrt_pass_cntr = htons(0xffff); in osst_init_aux()
571 /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */ in osst_init_aux()
572 par->first_frame_ppos = htonl(0); in osst_init_aux()
573 par->last_frame_ppos = htonl(0xbb7); in osst_init_aux()
574 aux->frame_seq_num = htonl(0); in osst_init_aux()
575 aux->logical_blk_num_high = htonl(0); in osst_init_aux()
576 aux->logical_blk_num = htonl(0); in osst_init_aux()
577 aux->next_mark_ppos = htonl(STp->first_mark_ppos); in osst_init_aux()
581 dat->dat_sz = 8; in osst_init_aux()
582 dat->reserved1 = 0; in osst_init_aux()
583 dat->entry_cnt = 1; in osst_init_aux()
584 dat->reserved3 = 0; in osst_init_aux()
585 dat->dat_list[0].blk_sz = htonl(blk_sz); in osst_init_aux()
586 dat->dat_list[0].blk_cnt = htons(blk_cnt); in osst_init_aux()
587 dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER? in osst_init_aux()
589 dat->dat_list[0].reserved = 0; in osst_init_aux()
591 aux->update_frame_cntr = htonl(0); in osst_init_aux()
592 par->partition_num = OS_DATA_PARTITION; in osst_init_aux()
593 par->par_desc_ver = OS_PARTITION_VERSION; in osst_init_aux()
594 par->wrt_pass_cntr = htons(STp->wrt_pass_cntr); in osst_init_aux()
595 par->first_frame_ppos = htonl(STp->first_data_ppos); in osst_init_aux()
596 par->last_frame_ppos = htonl(STp->capacity); in osst_init_aux()
597 aux->frame_seq_num = htonl(frame_seq_number); in osst_init_aux()
598 aux->logical_blk_num_high = htonl(0); in osst_init_aux()
599 aux->logical_blk_num = htonl(logical_blk_num); in osst_init_aux()
603 aux->filemark_cnt = htonl(STp->filemark_cnt); in osst_init_aux()
604 aux->phys_fm = htonl(0xffffffff); in osst_init_aux()
605 aux->last_mark_ppos = htonl(STp->last_mark_ppos); in osst_init_aux()
606 aux->last_mark_lbn = htonl(STp->last_mark_lbn); in osst_init_aux()
610 * Verify that we have the correct tape frame
615 os_aux_t * aux = STp->buffer->aux; in osst_verify_frame()
616 os_partition_t * par = &(aux->partition); in osst_verify_frame()
617 struct st_partstat * STps = &(STp->ps[STp->partition]); in osst_verify_frame()
620 if (STp->raw) { in osst_verify_frame()
621 if (STp->buffer->syscall_result) { in osst_verify_frame()
622 for (i=0; i < STp->buffer->sg_segs; i++) in osst_verify_frame()
623 memset(page_address(sg_page(&STp->buffer->sg[i])), in osst_verify_frame()
624 0, STp->buffer->sg[i].length); in osst_verify_frame()
625 strcpy(STp->buffer->b_data, "READ ERROR ON FRAME"); in osst_verify_frame()
627 STp->buffer->buffer_bytes = OS_FRAME_SIZE; in osst_verify_frame()
630 if (STp->buffer->syscall_result) { in osst_verify_frame()
632 printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name); in osst_verify_frame()
636 if (ntohl(aux->format_id) != 0) { in osst_verify_frame()
638 printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id)); in osst_verify_frame()
642 if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 && in osst_verify_frame()
643 (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) { in osst_verify_frame()
645 printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name); in osst_verify_frame()
649 if (par->partition_num != OS_DATA_PARTITION) { in osst_verify_frame()
650 if (!STp->linux_media || STp->linux_media_version != 2) { in osst_verify_frame()
652 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n", in osst_verify_frame()
653 name, par->partition_num); in osst_verify_frame()
658 if (par->par_desc_ver != OS_PARTITION_VERSION) { in osst_verify_frame()
660 printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver); in osst_verify_frame()
664 if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) { in osst_verify_frame()
666 printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", in osst_verify_frame()
667 name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr); in osst_verify_frame()
671 if (aux->frame_type != OS_FRAME_TYPE_DATA && in osst_verify_frame()
672 aux->frame_type != OS_FRAME_TYPE_EOD && in osst_verify_frame()
673 aux->frame_type != OS_FRAME_TYPE_MARKER) { in osst_verify_frame()
676 printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type); in osst_verify_frame()
681 if (aux->frame_type == OS_FRAME_TYPE_EOD && in osst_verify_frame()
682 STp->first_frame_position < STp->eod_frame_ppos) { in osst_verify_frame()
683 printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name, in osst_verify_frame()
684 STp->first_frame_position); in osst_verify_frame()
687 if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) { in osst_verify_frame()
690 printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n", in osst_verify_frame()
691 name, ntohl(aux->frame_seq_num), frame_seq_number); in osst_verify_frame()
696 if (aux->frame_type == OS_FRAME_TYPE_MARKER) { in osst_verify_frame()
697 STps->eof = ST_FM_HIT; in osst_verify_frame()
699 i = ntohl(aux->filemark_cnt); in osst_verify_frame()
700 if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt || in osst_verify_frame()
701 STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) { in osst_verify_frame()
703 printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name, in osst_verify_frame()
704 STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected", in osst_verify_frame()
705 i, STp->first_frame_position - 1); in osst_verify_frame()
707 STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1); in osst_verify_frame()
708 if (i >= STp->filemark_cnt) in osst_verify_frame()
709 STp->filemark_cnt = i+1; in osst_verify_frame()
712 if (aux->frame_type == OS_FRAME_TYPE_EOD) { in osst_verify_frame()
713 STps->eof = ST_EOD_1; in osst_verify_frame()
714 STp->frame_in_buffer = 1; in osst_verify_frame()
716 if (aux->frame_type == OS_FRAME_TYPE_DATA) { in osst_verify_frame()
717 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt); in osst_verify_frame()
718 blk_sz = ntohl(aux->dat.dat_list[0].blk_sz); in osst_verify_frame()
719 STp->buffer->buffer_bytes = blk_cnt * blk_sz; in osst_verify_frame()
720 STp->buffer->read_pointer = 0; in osst_verify_frame()
721 STp->frame_in_buffer = 1; in osst_verify_frame()
724 if (STp->block_size != blk_sz && blk_sz > 0) { in osst_verify_frame()
728 STp->block_size<1024?STp->block_size:STp->block_size/1024, in osst_verify_frame()
729 STp->block_size<1024?'b':'k'); in osst_verify_frame()
730 STp->block_size = blk_sz; in osst_verify_frame()
731 STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz; in osst_verify_frame()
733 STps->eof = ST_NOEOF; in osst_verify_frame()
735 STp->frame_seq_number = ntohl(aux->frame_seq_num); in osst_verify_frame()
736 STp->logical_blk_num = ntohl(aux->logical_blk_num); in osst_verify_frame()
740 if (STp->read_error_frame == 0) in osst_verify_frame()
741 STp->read_error_frame = STp->first_frame_position - 1; in osst_verify_frame()
767 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); in osst_wait_ready()
769 if (!SRpnt) return (-EBUSY); in osst_wait_ready()
771 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && in osst_wait_ready()
772 (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && in osst_wait_ready()
773 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) || in osst_wait_ready()
774 ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 && in osst_wait_ready()
775 SRpnt->sense[13] == 0 ) )) { in osst_wait_ready()
788 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); in osst_wait_ready()
794 if ( STp->buffer->syscall_result && in osst_wait_ready()
799 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], in osst_wait_ready()
800 SRpnt->sense[12], SRpnt->sense[13]); in osst_wait_ready()
802 return (-EIO); in osst_wait_ready()
828 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); in osst_wait_for_medium()
830 if (!SRpnt) return (-EBUSY); in osst_wait_for_medium()
832 while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) && in osst_wait_for_medium()
833 SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) { in osst_wait_for_medium()
846 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); in osst_wait_for_medium()
852 if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 && in osst_wait_for_medium()
853 SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) { in osst_wait_for_medium()
857 STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2], in osst_wait_for_medium()
858 SRpnt->sense[12], SRpnt->sense[13]); in osst_wait_for_medium()
868 …nt osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame) in osst_position_tape_and_confirm() argument
872 osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */ in osst_position_tape_and_confirm()
873 retval = osst_set_frame_position(STp, aSRpnt, frame, 0); in osst_position_tape_and_confirm()
891 printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name); in osst_flush_drive_buffer()
898 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); in osst_flush_drive_buffer()
900 if (!SRpnt) return (-EBUSY); in osst_flush_drive_buffer()
901 if (STp->buffer->syscall_result) { in osst_flush_drive_buffer()
902 if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) { in osst_flush_drive_buffer()
903 if (SRpnt->sense[13] == 8) { in osst_flush_drive_buffer()
910 STp->ps[STp->partition].rw = OS_WRITING_COMPLETE; in osst_flush_drive_buffer()
923 if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING) in osst_wait_frame()
924 printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name); in osst_wait_frame()
930 if (result == -EIO) in osst_wait_frame()
932 return 0; /* successful recovery leaves drive ready for frame */ in osst_wait_frame()
934 if (STp->first_frame_position == curr && in osst_wait_frame()
936 (signed)STp->last_frame_position > (signed)curr + minlast) || in osst_wait_frame()
937 (minlast >= 0 && STp->cur_frames > minlast) in osst_wait_frame()
943 "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n", in osst_wait_frame()
944 name, curr, curr+minlast, STp->first_frame_position, in osst_wait_frame()
945 STp->last_frame_position, STp->cur_frames, in osst_wait_frame()
946 result, (jiffies-startwait)/HZ, in osst_wait_frame()
947 (((jiffies-startwait)%HZ)*10)/HZ); in osst_wait_frame()
954 printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n", in osst_wait_frame()
955 name, curr, curr+minlast, STp->first_frame_position, in osst_wait_frame()
956 STp->last_frame_position, STp->cur_frames, result); in osst_wait_frame()
957 notyetprinted--; in osst_wait_frame()
963 printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n", in osst_wait_frame()
964 name, curr, curr+minlast, STp->first_frame_position, in osst_wait_frame()
965 STp->last_frame_position, STp->cur_frames, in osst_wait_frame()
966 (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ); in osst_wait_frame()
968 return -EBUSY; in osst_wait_frame()
981 char * olddata = STp->buffer->b_data; in osst_recover_wait_frame()
982 int oldsize = STp->buffer->buffer_size; in osst_recover_wait_frame()
984 /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */ in osst_recover_wait_frame()
989 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, in osst_recover_wait_frame()
994 if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) { in osst_recover_wait_frame()
996 /* some failure - not just not-ready */ in osst_recover_wait_frame()
1002 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; in osst_recover_wait_frame()
1006 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout, in osst_recover_wait_frame()
1009 retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 ); in osst_recover_wait_frame()
1010 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; in osst_recover_wait_frame()
1015 /* TODO - figure out which error conditions can be handled */ in osst_recover_wait_frame()
1016 if (STp->buffer->syscall_result) in osst_recover_wait_frame()
1019 (*aSRpnt)->sense[ 2] & 0x0f, in osst_recover_wait_frame()
1020 (*aSRpnt)->sense[12], in osst_recover_wait_frame()
1021 (*aSRpnt)->sense[13]); in osst_recover_wait_frame()
1027 * Read the next OnStream tape frame at the current location
1035 os_aux_t * aux = STp->buffer->aux; in osst_read_frame()
1039 if (STp->poll) in osst_read_frame()
1040 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout)) in osst_read_frame()
1050 printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); in osst_read_frame()
1053 STp->timeout, MAX_RETRIES, 1); in osst_read_frame()
1056 return (-EBUSY); in osst_read_frame()
1058 if ((STp->buffer)->syscall_result) { in osst_read_frame()
1060 if (STp->read_error_frame == 0) { in osst_read_frame()
1061 STp->read_error_frame = STp->first_frame_position; in osst_read_frame()
1063 printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame); in osst_read_frame()
1070 SRpnt->sense[0], SRpnt->sense[1], in osst_read_frame()
1071 SRpnt->sense[2], SRpnt->sense[3], in osst_read_frame()
1072 SRpnt->sense[4], SRpnt->sense[5], in osst_read_frame()
1073 SRpnt->sense[6], SRpnt->sense[7]); in osst_read_frame()
1077 STp->first_frame_position++; in osst_read_frame()
1082 sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i]; in osst_read_frame()
1086 ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr), in osst_read_frame()
1087 aux->frame_type==1?"EOD":aux->frame_type==2?"MARK": in osst_read_frame()
1088 aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", in osst_read_frame()
1089 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), in osst_read_frame()
1090 ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) ); in osst_read_frame()
1091 if (aux->frame_type==2) in osst_read_frame()
1093 ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn)); in osst_read_frame()
1094 printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval); in osst_read_frame()
1102 struct st_partstat * STps = &(STp->ps[STp->partition]); in osst_initiate_read()
1108 if (STps->rw != ST_READING) { /* Initialize read operation */ in osst_initiate_read()
1109 if (STps->rw == ST_WRITING || STp->dirty) { in osst_initiate_read()
1110 STp->write_type = OS_WRITE_DATA; in osst_initiate_read()
1114 STps->rw = ST_READING; in osst_initiate_read()
1115 STp->frame_in_buffer = 0; in osst_initiate_read()
1119 * read frames into its buffer. in osst_initiate_read()
1128 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); in osst_initiate_read()
1130 if ((retval = STp->buffer->syscall_result)) in osst_initiate_read()
1140 struct st_partstat * STps = &(STp->ps[STp->partition]); in osst_get_logical_frame()
1149 * If we want just any frame (-1) and there is a frame in the buffer, return it in osst_get_logical_frame()
1151 if (frame_seq_number == -1 && STp->frame_in_buffer) { in osst_get_logical_frame()
1153 printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number); in osst_get_logical_frame()
1155 return (STps->eof); in osst_get_logical_frame()
1158 * Search and wait for the next logical tape frame in osst_get_logical_frame()
1162 printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n", in osst_get_logical_frame()
1164 if (STp->read_error_frame) { in osst_get_logical_frame()
1165 osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0); in osst_get_logical_frame()
1167 printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n", in osst_get_logical_frame()
1168 name, STp->read_error_frame); in osst_get_logical_frame()
1170 STp->read_error_frame = 0; in osst_get_logical_frame()
1171 STp->abort_count++; in osst_get_logical_frame()
1173 return (-EIO); in osst_get_logical_frame()
1177 printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n", in osst_get_logical_frame()
1181 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) { in osst_get_logical_frame()
1182 if (STp->raw) in osst_get_logical_frame()
1183 return (-EIO); in osst_get_logical_frame()
1187 else if (position > STp->eod_frame_ppos || ++bad == 10) { in osst_get_logical_frame()
1188 position = STp->read_error_frame - 1; in osst_get_logical_frame()
1196 printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n", in osst_get_logical_frame()
1204 if (osst_verify_frame(STp, -1, quiet)) { in osst_get_logical_frame()
1205 x = ntohl(STp->buffer->aux->frame_seq_num); in osst_get_logical_frame()
1206 if (STp->fast_open) { in osst_get_logical_frame()
1208 "%s:W: Found logical frame %d instead of %d after fast open\n", in osst_get_logical_frame()
1210 STp->header_ok = 0; in osst_get_logical_frame()
1211 STp->read_error_frame = 0; in osst_get_logical_frame()
1212 return (-EIO); in osst_get_logical_frame()
1216 /* positioning backwards did not bring us to the desired frame */ in osst_get_logical_frame()
1217 position = STp->read_error_frame - 1; in osst_get_logical_frame()
1221 + frame_seq_number - x - 1; in osst_get_logical_frame()
1223 if (STp->first_frame_position >= 3000 && position < 3000) in osst_get_logical_frame()
1224 position -= 10; in osst_get_logical_frame()
1228 "%s:D: Found logical frame %d while looking for %d: back up %d\n", in osst_get_logical_frame()
1230 STp->first_frame_position - position); in osst_get_logical_frame()
1243 cnt--; in osst_get_logical_frame()
1245 STp->frame_in_buffer = 0; in osst_get_logical_frame()
1248 STp->recover_count++; in osst_get_logical_frame()
1249 STp->recover_erreg++; in osst_get_logical_frame()
1251 name, STp->read_error_frame); in osst_get_logical_frame()
1253 STp->read_count++; in osst_get_logical_frame()
1256 if (debugging || STps->eof) in osst_get_logical_frame()
1258 "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n", in osst_get_logical_frame()
1259 name, frame_seq_number, STp->frame_seq_number, STps->eof); in osst_get_logical_frame()
1261 STp->fast_open = 0; in osst_get_logical_frame()
1262 STp->read_error_frame = 0; in osst_get_logical_frame()
1263 return (STps->eof); in osst_get_logical_frame()
1268 struct st_partstat * STps = &(STp->ps[STp->partition]); in osst_seek_logical_blk()
1276 name, logical_blk_num, STp->logical_blk_num, in osst_seek_logical_blk()
1277 STp->block_size<1024?STp->block_size:STp->block_size/1024, in osst_seek_logical_blk()
1278 STp->block_size<1024?'b':'k'); in osst_seek_logical_blk()
1281 if (STps->drv_block >= 0) { in osst_seek_logical_blk()
1282 move = logical_blk_num - STp->logical_blk_num; in osst_seek_logical_blk()
1283 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; in osst_seek_logical_blk()
1284 move /= (OS_DATA_SIZE / STp->block_size); in osst_seek_logical_blk()
1285 frame_seq_estimate = STp->frame_seq_number + move; in osst_seek_logical_blk()
1287 frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE; in osst_seek_logical_blk()
1292 if (ppos_estimate > STp->eod_frame_ppos-2) { in osst_seek_logical_blk()
1293 frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate; in osst_seek_logical_blk()
1294 ppos_estimate = STp->eod_frame_ppos - 2; in osst_seek_logical_blk()
1302 /* we've located the estimated frame, now does it have our block? */ in osst_seek_logical_blk()
1303 if (logical_blk_num < STp->logical_blk_num || in osst_seek_logical_blk()
1304 … logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) { in osst_seek_logical_blk()
1305 if (STps->eof == ST_FM_HIT) in osst_seek_logical_blk()
1306 move = logical_blk_num < STp->logical_blk_num? -2 : 1; in osst_seek_logical_blk()
1308 move = logical_blk_num - STp->logical_blk_num; in osst_seek_logical_blk()
1309 if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; in osst_seek_logical_blk()
1310 move /= (OS_DATA_SIZE / STp->block_size); in osst_seek_logical_blk()
1312 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1; in osst_seek_logical_blk()
1316 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, in osst_seek_logical_blk()
1317 STp->logical_blk_num, logical_blk_num, move); in osst_seek_logical_blk()
1323 STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size; in osst_seek_logical_blk()
1324 STp->buffer->buffer_bytes -= STp->buffer->read_pointer; in osst_seek_logical_blk()
1325 STp->logical_blk_num = logical_blk_num; in osst_seek_logical_blk()
1329 name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, in osst_seek_logical_blk()
1330 STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, in osst_seek_logical_blk()
1331 STp->block_size); in osst_seek_logical_blk()
1333 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); in osst_seek_logical_blk()
1334 if (STps->eof == ST_FM_HIT) { in osst_seek_logical_blk()
1335 STps->drv_file++; in osst_seek_logical_blk()
1336 STps->drv_block = 0; in osst_seek_logical_blk()
1338 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? in osst_seek_logical_blk()
1339 STp->logical_blk_num - in osst_seek_logical_blk()
1340 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): in osst_seek_logical_blk()
1341 -1; in osst_seek_logical_blk()
1343 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; in osst_seek_logical_blk()
1347 if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0) in osst_seek_logical_blk()
1349 /* we are not yet at the estimated frame, adjust our estimate of its physical position */ in osst_seek_logical_blk()
1352 name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, in osst_seek_logical_blk()
1353 STp->logical_blk_num, logical_blk_num); in osst_seek_logical_blk()
1355 if (frame_seq_estimate != STp->frame_seq_number) in osst_seek_logical_blk()
1356 ppos_estimate += frame_seq_estimate - STp->frame_seq_number; in osst_seek_logical_blk()
1362 name, logical_blk_num, STp->logical_blk_num, retries); in osst_seek_logical_blk()
1363 return (-EIO); in osst_seek_logical_blk()
1366 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1369 * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1382 "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n", in osst_get_sector()
1383 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, in osst_get_sector()
1384 STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, in osst_get_sector()
1385 STp->ps[STp->partition].rw == ST_WRITING?'w':'r', in osst_get_sector()
1386 STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes: in osst_get_sector()
1387 STp->buffer->read_pointer, STp->ps[STp->partition].eof); in osst_get_sector()
1390 if (STp->ps[STp->partition].drv_block >= 0) { in osst_get_sector()
1391 sector = (STp->frame_in_buffer ? STp->first_frame_position-1 : in osst_get_sector()
1392 STp->first_frame_position) << OSST_FRAME_SHIFT; in osst_get_sector()
1393 if (STp->ps[STp->partition].rw == ST_WRITING) in osst_get_sector()
1394 sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; in osst_get_sector()
1396 sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK; in osst_get_sector()
1407 struct st_partstat * STps = &(STp->ps[STp->partition]); in osst_seek_sector()
1408 int frame = sector >> OSST_FRAME_SHIFT, in osst_seek_sector() local
1414 printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n", in osst_seek_sector()
1415 name, sector, frame, offset); in osst_seek_sector()
1417 if (frame < 0 || frame >= STp->capacity) return (-ENXIO); in osst_seek_sector()
1419 if (frame <= STp->first_data_ppos) { in osst_seek_sector()
1420 STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0; in osst_seek_sector()
1421 return (osst_set_frame_position(STp, aSRpnt, frame, 0)); in osst_seek_sector()
1423 r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0); in osst_seek_sector()
1426 r = osst_get_logical_frame(STp, aSRpnt, -1, 1); in osst_seek_sector()
1429 if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO); in osst_seek_sector()
1432 STp->logical_blk_num += offset / STp->block_size; in osst_seek_sector()
1433 STp->buffer->read_pointer = offset; in osst_seek_sector()
1434 STp->buffer->buffer_bytes -= offset; in osst_seek_sector()
1436 STp->frame_seq_number++; in osst_seek_sector()
1437 STp->frame_in_buffer = 0; in osst_seek_sector()
1438 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); in osst_seek_sector()
1439 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0; in osst_seek_sector()
1441 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt); in osst_seek_sector()
1442 if (STps->eof == ST_FM_HIT) { in osst_seek_sector()
1443 STps->drv_file++; in osst_seek_sector()
1444 STps->drv_block = 0; in osst_seek_sector()
1446 STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)? in osst_seek_sector()
1447 STp->logical_blk_num - in osst_seek_sector()
1448 (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0): in osst_seek_sector()
1449 -1; in osst_seek_sector()
1451 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF; in osst_seek_sector()
1454 "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n", in osst_seek_sector()
1455 name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num, in osst_seek_sector()
1456 STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof); in osst_seek_sector()
1462 * Read back the drive's internal buffer contents, as a part
1466 * drive's buffer must be of one type (DATA, MARK or EOD)!
1469 unsigned int frame, unsigned int skip, int pending) in osst_read_back_buffer_and_rewrite() argument
1472 unsigned char * buffer, * p; in osst_read_back_buffer_and_rewrite() local
1475 int nframes = STp->cur_frames; in osst_read_back_buffer_and_rewrite()
1476 int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); in osst_read_back_buffer_and_rewrite()
1477 int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num) in osst_read_back_buffer_and_rewrite()
1478 - (nframes + pending - 1); in osst_read_back_buffer_and_rewrite()
1479 int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num) in osst_read_back_buffer_and_rewrite()
1480 - (nframes + pending - 1) * blks_per_frame; in osst_read_back_buffer_and_rewrite()
1487 if ((buffer = vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL) in osst_read_back_buffer_and_rewrite()
1488 return (-EIO); in osst_read_back_buffer_and_rewrite()
1490 printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n", in osst_read_back_buffer_and_rewrite()
1493 osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE])); in osst_read_back_buffer_and_rewrite()
1496 printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n", in osst_read_back_buffer_and_rewrite()
1501 for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) { in osst_read_back_buffer_and_rewrite()
1504 cmd[0] = 0x3C; /* Buffer Read */ in osst_read_back_buffer_and_rewrite()
1510 STp->timeout, MAX_RETRIES, 1); in osst_read_back_buffer_and_rewrite()
1512 if ((STp->buffer)->syscall_result || !SRpnt) { in osst_read_back_buffer_and_rewrite()
1513 printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name); in osst_read_back_buffer_and_rewrite()
1514 vfree(buffer); in osst_read_back_buffer_and_rewrite()
1516 return (-EIO); in osst_read_back_buffer_and_rewrite()
1518 osst_copy_from_buffer(STp->buffer, p); in osst_read_back_buffer_and_rewrite()
1521 printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n", in osst_read_back_buffer_and_rewrite()
1529 printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames); in osst_read_back_buffer_and_rewrite()
1532 /* In the header we don't actually re-write the frames that fail, just the ones after them */ in osst_read_back_buffer_and_rewrite()
1534 for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) { in osst_read_back_buffer_and_rewrite()
1537 if (STp->write_type == OS_WRITE_HEADER) { in osst_read_back_buffer_and_rewrite()
1542 new_frame = 3000-i; in osst_read_back_buffer_and_rewrite()
1546 printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n", in osst_read_back_buffer_and_rewrite()
1554 if (new_frame > frame + 1000) { in osst_read_back_buffer_and_rewrite()
1556 vfree(buffer); in osst_read_back_buffer_and_rewrite()
1557 return (-EIO); in osst_read_back_buffer_and_rewrite()
1562 osst_copy_to_buffer(STp->buffer, p); in osst_read_back_buffer_and_rewrite()
1564 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type! in osst_read_back_buffer_and_rewrite()
1566 osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i, in osst_read_back_buffer_and_rewrite()
1568 ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame); in osst_read_back_buffer_and_rewrite()
1577 "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n", in osst_read_back_buffer_and_rewrite()
1582 STp->timeout, MAX_RETRIES, 1); in osst_read_back_buffer_and_rewrite()
1584 if (STp->buffer->syscall_result) in osst_read_back_buffer_and_rewrite()
1589 /* if we just sent the last frame, wait till all successfully written */ in osst_read_back_buffer_and_rewrite()
1592 printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name); in osst_read_back_buffer_and_rewrite()
1598 STp->timeout, MAX_RETRIES, 1); in osst_read_back_buffer_and_rewrite()
1601 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); in osst_read_back_buffer_and_rewrite()
1606 flag = STp->buffer->syscall_result; in osst_read_back_buffer_and_rewrite()
1612 SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, in osst_read_back_buffer_and_rewrite()
1615 if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && in osst_read_back_buffer_and_rewrite()
1616 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) { in osst_read_back_buffer_and_rewrite()
1621 if (STp->buffer->syscall_result) in osst_read_back_buffer_and_rewrite()
1627 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name); in osst_read_back_buffer_and_rewrite()
1633 if ((SRpnt->sense[ 2] & 0x0f) == 13 && in osst_read_back_buffer_and_rewrite()
1634 SRpnt->sense[12] == 0 && in osst_read_back_buffer_and_rewrite()
1635 SRpnt->sense[13] == 2) { in osst_read_back_buffer_and_rewrite()
1637 vfree(buffer); in osst_read_back_buffer_and_rewrite()
1638 return (-EIO); /* hit end of tape = fail */ in osst_read_back_buffer_and_rewrite()
1640 i = ((SRpnt->sense[3] << 24) | in osst_read_back_buffer_and_rewrite()
1641 (SRpnt->sense[4] << 16) | in osst_read_back_buffer_and_rewrite()
1642 (SRpnt->sense[5] << 8) | in osst_read_back_buffer_and_rewrite()
1643 SRpnt->sense[6] ) - new_frame; in osst_read_back_buffer_and_rewrite()
1644 p = &buffer[i * OS_DATA_SIZE]; in osst_read_back_buffer_and_rewrite()
1650 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n", in osst_read_back_buffer_and_rewrite()
1651 name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames); in osst_read_back_buffer_and_rewrite()
1658 STp->write_type == OS_WRITE_HEADER?"header":"body"); in osst_read_back_buffer_and_rewrite()
1661 osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */ in osst_read_back_buffer_and_rewrite()
1662 vfree(buffer); in osst_read_back_buffer_and_rewrite()
1667 unsigned int frame, unsigned int skip, int pending) in osst_reposition_and_retry() argument
1685 if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990) in osst_reposition_and_retry()
1686 frame = 3000-skip; in osst_reposition_and_retry()
1687 expected = frame+skip+STp->cur_frames+pending; in osst_reposition_and_retry()
1689 printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n", in osst_reposition_and_retry()
1690 name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending); in osst_reposition_and_retry()
1692 osst_set_frame_position(STp, aSRpnt, frame + skip, 1); in osst_reposition_and_retry()
1694 attempts--; in osst_reposition_and_retry()
1699 printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n", in osst_reposition_and_retry()
1700 name, STp->first_frame_position, in osst_reposition_and_retry()
1701 STp->last_frame_position, STp->cur_frames); in osst_reposition_and_retry()
1703 frame = STp->last_frame_position; in osst_reposition_and_retry()
1707 if (pending && STp->cur_frames < 50) { in osst_reposition_and_retry()
1715 name, STp->frame_seq_number-1, STp->first_frame_position); in osst_reposition_and_retry()
1718 STp->timeout, MAX_RETRIES, 1); in osst_reposition_and_retry()
1721 if (STp->buffer->syscall_result) { /* additional write error */ in osst_reposition_and_retry()
1722 if ((SRpnt->sense[ 2] & 0x0f) == 13 && in osst_reposition_and_retry()
1723 SRpnt->sense[12] == 0 && in osst_reposition_and_retry()
1724 SRpnt->sense[13] == 2) { in osst_reposition_and_retry()
1737 if (STp->cur_frames == 0) { in osst_reposition_and_retry()
1740 printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name); in osst_reposition_and_retry()
1742 if (STp->first_frame_position != expected) { in osst_reposition_and_retry()
1743 printk(KERN_ERR "%s:A: Actual position %d - expected %d\n", in osst_reposition_and_retry()
1744 name, STp->first_frame_position, expected); in osst_reposition_and_retry()
1745 return (-EIO); in osst_reposition_and_retry()
1751 printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); in osst_reposition_and_retry()
1762 return (-EIO); in osst_reposition_and_retry()
1772 struct st_partstat * STps = & STp->ps[STp->partition]; in osst_write_error_recovery()
1776 unsigned int frame, skip; in osst_write_error_recovery() local
1778 rw_state = STps->rw; in osst_write_error_recovery()
1780 if ((SRpnt->sense[ 2] & 0x0f) != 3 in osst_write_error_recovery()
1781 || SRpnt->sense[12] != 12 in osst_write_error_recovery()
1782 || SRpnt->sense[13] != 0) { in osst_write_error_recovery()
1785 SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]); in osst_write_error_recovery()
1787 return (-EIO); in osst_write_error_recovery()
1789 frame = (SRpnt->sense[3] << 24) | in osst_write_error_recovery()
1790 (SRpnt->sense[4] << 16) | in osst_write_error_recovery()
1791 (SRpnt->sense[5] << 8) | in osst_write_error_recovery()
1792 SRpnt->sense[6]; in osst_write_error_recovery()
1793 skip = SRpnt->sense[9]; in osst_write_error_recovery()
1796 …printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, … in osst_write_error_recovery()
1800 printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n", in osst_write_error_recovery()
1801 name, STp->first_frame_position, STp->last_frame_position); in osst_write_error_recovery()
1803 switch (STp->write_type) { in osst_write_error_recovery()
1809 name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip); in osst_write_error_recovery()
1810 if (STp->os_fw_rev >= 10600) in osst_write_error_recovery()
1811 retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending); in osst_write_error_recovery()
1813 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending); in osst_write_error_recovery()
1820 printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name); in osst_write_error_recovery()
1821 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0); in osst_write_error_recovery()
1822 retval = -EIO; in osst_write_error_recovery()
1825 printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name); in osst_write_error_recovery()
1826 retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending); in osst_write_error_recovery()
1829 printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name); in osst_write_error_recovery()
1830 osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0); in osst_write_error_recovery()
1835 name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position); in osst_write_error_recovery()
1836 printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num); in osst_write_error_recovery()
1839 STp->recover_count++; in osst_write_error_recovery()
1840 STp->recover_erreg++; in osst_write_error_recovery()
1842 STp->abort_count++; in osst_write_error_recovery()
1844 STps->rw = rw_state; in osst_write_error_recovery()
1853 int last_mark_ppos = -1; in osst_space_over_filemarks_backward()
1858 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_backward()
1862 return -EIO; in osst_space_over_filemarks_backward()
1864 if (STp->linux_media_version >= 4) { in osst_space_over_filemarks_backward()
1868 cnt = ntohl(STp->buffer->aux->filemark_cnt); in osst_space_over_filemarks_backward()
1869 if (STp->header_ok && in osst_space_over_filemarks_backward()
1870 STp->header_cache != NULL && in osst_space_over_filemarks_backward()
1871 (cnt - mt_count) >= 0 && in osst_space_over_filemarks_backward()
1872 (cnt - mt_count) < OS_FM_TAB_MAX && in osst_space_over_filemarks_backward()
1873 (cnt - mt_count) < STp->filemark_cnt && in osst_space_over_filemarks_backward()
1874 STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos) in osst_space_over_filemarks_backward()
1876 last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]); in osst_space_over_filemarks_backward()
1878 if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX) in osst_space_over_filemarks_backward()
1880 STp->header_cache == NULL?"lack of header cache":"count out of range"); in osst_space_over_filemarks_backward()
1884 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || in osst_space_over_filemarks_backward()
1885 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == in osst_space_over_filemarks_backward()
1886 STp->buffer->aux->last_mark_ppos))?"match":"error", in osst_space_over_filemarks_backward()
1889 if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) { in osst_space_over_filemarks_backward()
1891 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_backward()
1896 return (-EIO); in osst_space_over_filemarks_backward()
1898 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { in osst_space_over_filemarks_backward()
1901 return (-EIO); in osst_space_over_filemarks_backward()
1911 last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos); in osst_space_over_filemarks_backward()
1912 if (last_mark_ppos == -1) in osst_space_over_filemarks_backward()
1913 return (-EIO); in osst_space_over_filemarks_backward()
1919 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_backward()
1923 return (-EIO); in osst_space_over_filemarks_backward()
1925 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { in osst_space_over_filemarks_backward()
1928 return (-EIO); in osst_space_over_filemarks_backward()
1933 STp->frame_seq_number++; in osst_space_over_filemarks_backward()
1934 STp->frame_in_buffer = 0; in osst_space_over_filemarks_backward()
1935 STp->buffer->buffer_bytes = 0; in osst_space_over_filemarks_backward()
1936 STp->buffer->read_pointer = 0; in osst_space_over_filemarks_backward()
1937 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); in osst_space_over_filemarks_backward()
1956 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_forward_slow()
1960 return (-EIO); in osst_space_over_filemarks_forward_slow()
1963 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_forward_slow()
1967 return (-EIO); in osst_space_over_filemarks_forward_slow()
1969 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER) in osst_space_over_filemarks_forward_slow()
1971 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) { in osst_space_over_filemarks_forward_slow()
1975 if (STp->first_frame_position > STp->eod_frame_ppos+1) { in osst_space_over_filemarks_forward_slow()
1978 name, STp->eod_frame_ppos, STp->first_frame_position-1); in osst_space_over_filemarks_forward_slow()
1980 STp->eod_frame_ppos = STp->first_frame_position-1; in osst_space_over_filemarks_forward_slow()
1982 return (-EIO); in osst_space_over_filemarks_forward_slow()
1986 STp->frame_in_buffer = 0; in osst_space_over_filemarks_forward_slow()
1989 STp->frame_seq_number++; in osst_space_over_filemarks_forward_slow()
1990 STp->frame_in_buffer = 0; in osst_space_over_filemarks_forward_slow()
1991 STp->buffer->buffer_bytes = 0; in osst_space_over_filemarks_forward_slow()
1992 STp->buffer->read_pointer = 0; in osst_space_over_filemarks_forward_slow()
1993 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); in osst_space_over_filemarks_forward_slow()
2006 next_mark_ppos = -1; in osst_space_over_filemarks_forward_fast()
2011 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_forward_fast()
2015 return (-EIO); in osst_space_over_filemarks_forward_fast()
2018 if (STp->linux_media_version >= 4) { in osst_space_over_filemarks_forward_fast()
2022 cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1; in osst_space_over_filemarks_forward_fast()
2023 if (STp->header_ok && in osst_space_over_filemarks_forward_fast()
2024 STp->header_cache != NULL && in osst_space_over_filemarks_forward_fast()
2026 (cnt + mt_count) < STp->filemark_cnt && in osst_space_over_filemarks_forward_fast()
2027 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || in osst_space_over_filemarks_forward_fast()
2028 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos))) in osst_space_over_filemarks_forward_fast()
2030 next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]); in osst_space_over_filemarks_forward_fast()
2032 if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX) in osst_space_over_filemarks_forward_fast()
2034 STp->header_cache == NULL?"lack of header cache":"count out of range"); in osst_space_over_filemarks_forward_fast()
2038 ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) || in osst_space_over_filemarks_forward_fast()
2039 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == in osst_space_over_filemarks_forward_fast()
2040 STp->buffer->aux->last_mark_ppos))?"match":"error", in osst_space_over_filemarks_forward_fast()
2043 if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) { in osst_space_over_filemarks_forward_fast()
2050 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_forward_fast()
2055 return (-EIO); in osst_space_over_filemarks_forward_fast()
2057 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { in osst_space_over_filemarks_forward_fast()
2060 return (-EIO); in osst_space_over_filemarks_forward_fast()
2062 if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) { in osst_space_over_filemarks_forward_fast()
2065 ntohl(STp->buffer->aux->filemark_cnt)); in osst_space_over_filemarks_forward_fast()
2066 return (-EIO); in osst_space_over_filemarks_forward_fast()
2074 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER) in osst_space_over_filemarks_forward_fast()
2076 if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) { in osst_space_over_filemarks_forward_fast()
2080 return (-EIO); in osst_space_over_filemarks_forward_fast()
2082 if (ntohl(STp->buffer->aux->filemark_cnt) == 0) { in osst_space_over_filemarks_forward_fast()
2083 if (STp->first_mark_ppos == -1) { in osst_space_over_filemarks_forward_fast()
2089 osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos); in osst_space_over_filemarks_forward_fast()
2090 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_forward_fast()
2096 return (-EIO); in osst_space_over_filemarks_forward_fast()
2098 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { in osst_space_over_filemarks_forward_fast()
2100 name, STp->first_mark_ppos); in osst_space_over_filemarks_forward_fast()
2101 return (-EIO); in osst_space_over_filemarks_forward_fast()
2105 return (-EIO); in osst_space_over_filemarks_forward_fast()
2111 next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos); in osst_space_over_filemarks_forward_fast()
2112 if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) { in osst_space_over_filemarks_forward_fast()
2116 return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt); in osst_space_over_filemarks_forward_fast()
2123 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_space_over_filemarks_forward_fast()
2128 return (-EIO); in osst_space_over_filemarks_forward_fast()
2130 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) { in osst_space_over_filemarks_forward_fast()
2133 return (-EIO); in osst_space_over_filemarks_forward_fast()
2138 STp->frame_seq_number++; in osst_space_over_filemarks_forward_fast()
2139 STp->frame_in_buffer = 0; in osst_space_over_filemarks_forward_fast()
2140 STp->buffer->buffer_bytes = 0; in osst_space_over_filemarks_forward_fast()
2141 STp->buffer->read_pointer = 0; in osst_space_over_filemarks_forward_fast()
2142 STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); in osst_space_over_filemarks_forward_fast()
2163 (STp->buffer)->b_data[0] = cmd[4] - 1; in osst_set_retries()
2164 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */ in osst_set_retries()
2165 (STp->buffer)->b_data[2] = 0; /* Reserved */ in osst_set_retries()
2166 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */ in osst_set_retries()
2167 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7); in osst_set_retries()
2168 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2; in osst_set_retries()
2169 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4; in osst_set_retries()
2170 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries; in osst_set_retries()
2175 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); in osst_set_retries()
2178 if ((STp->buffer)->syscall_result) in osst_set_retries()
2187 int this_mark_ppos = STp->first_frame_position; in osst_write_filemark()
2188 int this_mark_lbn = STp->logical_blk_num; in osst_write_filemark()
2193 if (STp->raw) return 0; in osst_write_filemark()
2195 STp->write_type = OS_WRITE_NEW_MARK; in osst_write_filemark()
2198 name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn); in osst_write_filemark()
2200 STp->dirty = 1; in osst_write_filemark()
2203 STp->last_mark_ppos = this_mark_ppos; in osst_write_filemark()
2204 STp->last_mark_lbn = this_mark_lbn; in osst_write_filemark()
2205 if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX) in osst_write_filemark()
2206 STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos); in osst_write_filemark()
2207 if (STp->filemark_cnt++ == 0) in osst_write_filemark()
2208 STp->first_mark_ppos = this_mark_ppos; in osst_write_filemark()
2219 if (STp->raw) return 0; in osst_write_eod()
2221 STp->write_type = OS_WRITE_EOD; in osst_write_eod()
2222 STp->eod_frame_ppos = STp->first_frame_position; in osst_write_eod()
2225 STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num); in osst_write_eod()
2227 STp->dirty = 1; in osst_write_eod()
2231 STp->eod_frame_lfa = --(STp->frame_seq_number); in osst_write_eod()
2244 STp->write_type = OS_WRITE_FILLER; in osst_write_filler()
2245 while (count--) { in osst_write_filler()
2246 memcpy(STp->buffer->b_data, "Filler", 6); in osst_write_filler()
2247 STp->buffer->buffer_bytes = 6; in osst_write_filler()
2248 STp->dirty = 1; in osst_write_filler()
2250 printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name); in osst_write_filler()
2251 return (-EIO); in osst_write_filler()
2270 STp->write_type = OS_WRITE_HEADER; in __osst_write_header()
2271 while (count--) { in __osst_write_header()
2272 osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache); in __osst_write_header()
2273 STp->buffer->buffer_bytes = sizeof(os_header_t); in __osst_write_header()
2274 STp->dirty = 1; in __osst_write_header()
2276 printk(KERN_INFO "%s:I: Couldn't write header frame\n", name); in __osst_write_header()
2277 return (-EIO); in __osst_write_header()
2296 if (STp->raw) return 0; in osst_write_header()
2298 if (STp->header_cache == NULL) { in osst_write_header()
2299 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) { in osst_write_header()
2301 return (-ENOMEM); in osst_write_header()
2303 memset(STp->header_cache, 0, sizeof(os_header_t)); in osst_write_header()
2308 if (STp->header_ok) STp->update_frame_cntr++; in osst_write_header()
2309 else STp->update_frame_cntr = 0; in osst_write_header()
2311 header = STp->header_cache; in osst_write_header()
2312 strcpy(header->ident_str, "ADR_SEQ"); in osst_write_header()
2313 header->major_rev = 1; in osst_write_header()
2314 header->minor_rev = 4; in osst_write_header()
2315 header->ext_trk_tb_off = htons(17192); in osst_write_header()
2316 header->pt_par_num = 1; in osst_write_header()
2317 header->partition[0].partition_num = OS_DATA_PARTITION; in osst_write_header()
2318 header->partition[0].par_desc_ver = OS_PARTITION_VERSION; in osst_write_header()
2319 header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr); in osst_write_header()
2320 header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos); in osst_write_header()
2321 header->partition[0].last_frame_ppos = htonl(STp->capacity); in osst_write_header()
2322 header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos); in osst_write_header()
2323 header->cfg_col_width = htonl(20); in osst_write_header()
2324 header->dat_col_width = htonl(1500); in osst_write_header()
2325 header->qfa_col_width = htonl(0); in osst_write_header()
2326 header->ext_track_tb.nr_stream_part = 1; in osst_write_header()
2327 header->ext_track_tb.et_ent_sz = 32; in osst_write_header()
2328 header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0; in osst_write_header()
2329 header->ext_track_tb.dat_ext_trk_ey.fmt = 1; in osst_write_header()
2330 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736); in osst_write_header()
2331 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0; in osst_write_header()
2332 header->ext_track_tb.dat_ext_trk_ey.last_hlb = htonl(STp->eod_frame_lfa); in osst_write_header()
2333 header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos); in osst_write_header()
2334 header->dat_fm_tab.fm_part_num = 0; in osst_write_header()
2335 header->dat_fm_tab.fm_tab_ent_sz = 4; in osst_write_header()
2336 header->dat_fm_tab.fm_tab_ent_cnt = htons(STp->filemark_cnt<OS_FM_TAB_MAX? in osst_write_header()
2337 STp->filemark_cnt:OS_FM_TAB_MAX); in osst_write_header()
2340 if (STp->update_frame_cntr == 0) in osst_write_header()
2346 printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos); in osst_write_header()
2348 osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0); in osst_write_header()
2353 memcpy(STp->application_sig, "LIN4", 4); in osst_write_header()
2354 STp->linux_media = 1; in osst_write_header()
2355 STp->linux_media_version = 4; in osst_write_header()
2356 STp->header_ok = 1; in osst_write_header()
2363 if (STp->header_cache != NULL) in osst_reset_header()
2364 memset(STp->header_cache, 0, sizeof(os_header_t)); in osst_reset_header()
2366 STp->logical_blk_num = STp->frame_seq_number = 0; in osst_reset_header()
2367 STp->frame_in_buffer = 0; in osst_reset_header()
2368 STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A; in osst_reset_header()
2369 STp->filemark_cnt = 0; in osst_reset_header()
2370 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1; in osst_reset_header()
2383 if (STp->raw) in __osst_analyze_headers()
2386 if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) { in __osst_analyze_headers()
2397 printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name); in __osst_analyze_headers()
2401 header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */ in __osst_analyze_headers()
2402 aux = STp->buffer->aux; in __osst_analyze_headers()
2403 if (aux->frame_type != OS_FRAME_TYPE_HEADER) { in __osst_analyze_headers()
2405 printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos); in __osst_analyze_headers()
2409 if (ntohl(aux->frame_seq_num) != 0 || in __osst_analyze_headers()
2410 ntohl(aux->logical_blk_num) != 0 || in __osst_analyze_headers()
2411 aux->partition.partition_num != OS_CONFIG_PARTITION || in __osst_analyze_headers()
2412 ntohl(aux->partition.first_frame_ppos) != 0 || in __osst_analyze_headers()
2413 ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) { in __osst_analyze_headers()
2415 printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name, in __osst_analyze_headers()
2416 ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num), in __osst_analyze_headers()
2417 aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos), in __osst_analyze_headers()
2418 ntohl(aux->partition.last_frame_ppos)); in __osst_analyze_headers()
2422 if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 && in __osst_analyze_headers()
2423 strncmp(header->ident_str, "ADR-SEQ", 7) != 0) { in __osst_analyze_headers()
2424 strlcpy(id_string, header->ident_str, 8); in __osst_analyze_headers()
2430 update_frame_cntr = ntohl(aux->update_frame_cntr); in __osst_analyze_headers()
2431 if (update_frame_cntr < STp->update_frame_cntr) { in __osst_analyze_headers()
2433 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n", in __osst_analyze_headers()
2434 name, ppos, update_frame_cntr, STp->update_frame_cntr); in __osst_analyze_headers()
2438 if (header->major_rev != 1 || header->minor_rev != 4 ) { in __osst_analyze_headers()
2441 name, (header->major_rev != 1 || header->minor_rev < 2 || in __osst_analyze_headers()
2442 header->minor_rev > 4 )? "Invalid" : "Warning:", in __osst_analyze_headers()
2443 header->major_rev, header->minor_rev); in __osst_analyze_headers()
2445 if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4) in __osst_analyze_headers()
2449 if (header->pt_par_num != 1) in __osst_analyze_headers()
2451 name, header->pt_par_num); in __osst_analyze_headers()
2453 memcpy(id_string, aux->application_sig, 4); in __osst_analyze_headers()
2456 STp->linux_media = 1; in __osst_analyze_headers()
2457 linux_media_version = id_string[3] - '0'; in __osst_analyze_headers()
2465 if (linux_media_version < STp->linux_media_version) { in __osst_analyze_headers()
2467 printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n", in __osst_analyze_headers()
2472 if (linux_media_version > STp->linux_media_version) { in __osst_analyze_headers()
2474 printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n", in __osst_analyze_headers()
2477 memcpy(STp->application_sig, id_string, 5); in __osst_analyze_headers()
2478 STp->linux_media_version = linux_media_version; in __osst_analyze_headers()
2479 STp->update_frame_cntr = -1; in __osst_analyze_headers()
2481 if (update_frame_cntr > STp->update_frame_cntr) { in __osst_analyze_headers()
2483 printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n", in __osst_analyze_headers()
2486 if (STp->header_cache == NULL) { in __osst_analyze_headers()
2487 if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) { in __osst_analyze_headers()
2495 osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache); in __osst_analyze_headers()
2496 header = STp->header_cache; /* further accesses from cached (full) copy */ in __osst_analyze_headers()
2498 STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr); in __osst_analyze_headers()
2499 STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos); in __osst_analyze_headers()
2500 STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos); in __osst_analyze_headers()
2501 STp->eod_frame_lfa = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb); in __osst_analyze_headers()
2502 STp->filemark_cnt = ntohl(aux->filemark_cnt); in __osst_analyze_headers()
2503 STp->first_mark_ppos = ntohl(aux->next_mark_ppos); in __osst_analyze_headers()
2504 STp->last_mark_ppos = ntohl(aux->last_mark_ppos); in __osst_analyze_headers()
2505 STp->last_mark_lbn = ntohl(aux->last_mark_lbn); in __osst_analyze_headers()
2506 STp->update_frame_cntr = update_frame_cntr; in __osst_analyze_headers()
2508 printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n", in __osst_analyze_headers()
2509 name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt); in __osst_analyze_headers()
2510 printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name, in __osst_analyze_headers()
2511 STp->first_data_ppos, in __osst_analyze_headers()
2512 ntohl(header->partition[0].last_frame_ppos), in __osst_analyze_headers()
2513 ntohl(header->partition[0].eod_frame_ppos)); in __osst_analyze_headers()
2514 printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n", in __osst_analyze_headers()
2515 name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos); in __osst_analyze_headers()
2517 if (header->minor_rev < 4 && STp->linux_media_version == 4) { in __osst_analyze_headers()
2521 memcpy((void *)header->dat_fm_tab.fm_tab_ent, in __osst_analyze_headers()
2522 (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent)); in __osst_analyze_headers()
2523 memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list)); in __osst_analyze_headers()
2525 if (header->minor_rev == 4 && in __osst_analyze_headers()
2526 (header->ext_trk_tb_off != htons(17192) || in __osst_analyze_headers()
2527 header->partition[0].partition_num != OS_DATA_PARTITION || in __osst_analyze_headers()
2528 header->partition[0].par_desc_ver != OS_PARTITION_VERSION || in __osst_analyze_headers()
2529 header->partition[0].last_frame_ppos != htonl(STp->capacity) || in __osst_analyze_headers()
2530 header->cfg_col_width != htonl(20) || in __osst_analyze_headers()
2531 header->dat_col_width != htonl(1500) || in __osst_analyze_headers()
2532 header->qfa_col_width != htonl(0) || in __osst_analyze_headers()
2533 header->ext_track_tb.nr_stream_part != 1 || in __osst_analyze_headers()
2534 header->ext_track_tb.et_ent_sz != 32 || in __osst_analyze_headers()
2535 header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION || in __osst_analyze_headers()
2536 header->ext_track_tb.dat_ext_trk_ey.fmt != 1 || in __osst_analyze_headers()
2537 header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) || in __osst_analyze_headers()
2538 header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 || in __osst_analyze_headers()
2539 header->ext_track_tb.dat_ext_trk_ey.last_pp != htonl(STp->eod_frame_ppos) || in __osst_analyze_headers()
2540 header->dat_fm_tab.fm_part_num != OS_DATA_PARTITION || in __osst_analyze_headers()
2541 header->dat_fm_tab.fm_tab_ent_sz != 4 || in __osst_analyze_headers()
2542 header->dat_fm_tab.fm_tab_ent_cnt != in __osst_analyze_headers()
2543 htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX))) in __osst_analyze_headers()
2560 if (STp->raw) { in osst_analyze_headers()
2561 STp->header_ok = STp->linux_media = 1; in osst_analyze_headers()
2562 STp->linux_media_version = 0; in osst_analyze_headers()
2565 STp->header_ok = STp->linux_media = STp->linux_media_version = 0; in osst_analyze_headers()
2566 STp->wrt_pass_cntr = STp->update_frame_cntr = -1; in osst_analyze_headers()
2567 STp->eod_frame_ppos = STp->first_data_ppos = -1; in osst_analyze_headers()
2568 STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1; in osst_analyze_headers()
2573 /* optimization for speed - if we are positioned at ppos 10, read second group first */ in osst_analyze_headers()
2592 STp->eod_frame_ppos = STp->first_data_ppos = 0; in osst_analyze_headers()
2596 if (position <= STp->first_data_ppos) { in osst_analyze_headers()
2597 position = STp->first_data_ppos; in osst_analyze_headers()
2598 STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0; in osst_analyze_headers()
2601 STp->header_ok = 1; in osst_analyze_headers()
2608 int frame_position = STp->first_frame_position; in osst_verify_position()
2609 int frame_seq_numbr = STp->frame_seq_number; in osst_verify_position()
2610 int logical_blk_num = STp->logical_blk_num; in osst_verify_position()
2611 int halfway_frame = STp->frame_in_buffer; in osst_verify_position()
2612 int read_pointer = STp->buffer->read_pointer; in osst_verify_position()
2613 int prev_mark_ppos = -1; in osst_verify_position()
2620 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); in osst_verify_position()
2621 if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { in osst_verify_position()
2625 return (-EIO); in osst_verify_position()
2627 if (STp->linux_media_version >= 4) { in osst_verify_position()
2628 for (i=0; i<STp->filemark_cnt; i++) in osst_verify_position()
2629 if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position) in osst_verify_position()
2632 prev_mark_ppos = frame_position - 1; /* usually - we don't really know */ in osst_verify_position()
2633 actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ? in osst_verify_position()
2634 frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos); in osst_verify_position()
2635 if (frame_position != STp->first_frame_position || in osst_verify_position()
2636 frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) || in osst_verify_position()
2639 printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name, in osst_verify_position()
2640 STp->first_frame_position, frame_position, in osst_verify_position()
2641 STp->frame_seq_number + (halfway_frame?0:1), in osst_verify_position()
2644 return (-EIO); in osst_verify_position()
2647 /* prepare buffer for append and rewrite on top of original */ in osst_verify_position()
2648 osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); in osst_verify_position()
2649 STp->buffer->buffer_bytes = read_pointer; in osst_verify_position()
2650 STp->ps[STp->partition].rw = ST_WRITING; in osst_verify_position()
2651 STp->dirty = 1; in osst_verify_position()
2653 STp->frame_in_buffer = halfway_frame; in osst_verify_position()
2654 STp->frame_seq_number = frame_seq_numbr; in osst_verify_position()
2655 STp->logical_blk_num = logical_blk_num; in osst_verify_position()
2668 return (str[0]-'0')*10000 in osst_parse_firmware_rev()
2669 +(str[2]-'0')*1000 in osst_parse_firmware_rev()
2670 +(str[3]-'0')*100; in osst_parse_firmware_rev()
2672 return (str[0]-'0')*10000 in osst_parse_firmware_rev()
2673 +(str[1]-'0')*1000 in osst_parse_firmware_rev()
2674 +(str[2]-'0')*100 - 100 in osst_parse_firmware_rev()
2675 +(str[3]-'@'); in osst_parse_firmware_rev()
2693 if (STp->ready != ST_READY) { in osst_configure_onstream()
2697 return (-EIO); in osst_configure_onstream()
2700 if (STp->os_fw_rev < 10600) { in osst_configure_onstream()
2701 … printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev); in osst_configure_onstream()
2706 * Configure 32.5KB (data+aux) frame size. in osst_configure_onstream()
2707 * Get the current frame size from the block size mode page in osst_configure_onstream()
2715 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); in osst_configure_onstream()
2720 return (-EBUSY); in osst_configure_onstream()
2723 if ((STp->buffer)->syscall_result != 0) { in osst_configure_onstream()
2725 return (-EIO); in osst_configure_onstream()
2728 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; in osst_configure_onstream()
2729 …bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + he… in osst_configure_onstream()
2732 printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No"); in osst_configure_onstream()
2733 printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No"); in osst_configure_onstream()
2734 printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No"); in osst_configure_onstream()
2735 printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No"); in osst_configure_onstream()
2741 bs->one = 1; in osst_configure_onstream()
2742 bs->play32 = 0; in osst_configure_onstream()
2743 bs->play32_5 = 1; in osst_configure_onstream()
2744 bs->record32 = 0; in osst_configure_onstream()
2745 bs->record32_5 = 1; in osst_configure_onstream()
2752 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); in osst_configure_onstream()
2754 if ((STp->buffer)->syscall_result != 0) { in osst_configure_onstream()
2756 return (-EIO); in osst_configure_onstream()
2778 header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1; in osst_configure_onstream()
2779 header->medium_type = 0; /* Medium Type - ignoring */ in osst_configure_onstream()
2780 header->dsp = 0; /* Reserved */ in osst_configure_onstream()
2781 header->bdl = 0; /* Block Descriptor Length */ in osst_configure_onstream()
2783 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7); in osst_configure_onstream()
2784 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6; in osst_configure_onstream()
2785 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L'; in osst_configure_onstream()
2786 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I'; in osst_configure_onstream()
2787 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N'; in osst_configure_onstream()
2788 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4'; in osst_configure_onstream()
2789 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0; in osst_configure_onstream()
2790 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0; in osst_configure_onstream()
2792 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); in osst_configure_onstream()
2795 if ((STp->buffer)->syscall_result != 0) { in osst_configure_onstream()
2797 (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2)); in osst_configure_onstream()
2798 return (-EIO); in osst_configure_onstream()
2807 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); in osst_configure_onstream()
2810 if ((STp->buffer)->syscall_result != 0) { in osst_configure_onstream()
2812 return (-EIO); in osst_configure_onstream()
2815 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; in osst_configure_onstream()
2816 cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data + in osst_configure_onstream()
2817 sizeof(osst_mode_parameter_header_t) + header->bdl); in osst_configure_onstream()
2819 drive_buffer_size = ntohs(cp->buffer_size) / 2; in osst_configure_onstream()
2827 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); in osst_configure_onstream()
2830 if ((STp->buffer)->syscall_result != 0) { in osst_configure_onstream()
2832 return (-EIO); in osst_configure_onstream()
2835 header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data; in osst_configure_onstream()
2836 prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data + in osst_configure_onstream()
2837 sizeof(osst_mode_parameter_header_t) + header->bdl); in osst_configure_onstream()
2839 STp->density = prm->density; in osst_configure_onstream()
2840 STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks); in osst_configure_onstream()
2842 printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n", in osst_configure_onstream()
2843 name, STp->density, STp->capacity / 32, drive_buffer_size); in osst_configure_onstream()
2870 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1); in cross_eof()
2889 /* KG: We want to be able to use it for checking Write Buffer availability in osst_get_frame_position()
2892 char * olddata = STp->buffer->b_data; in osst_get_frame_position()
2893 int oldsize = STp->buffer->buffer_size; in osst_get_frame_position()
2895 if (STp->ready != ST_READY) return (-EIO); in osst_get_frame_position()
2900 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; in osst_get_frame_position()
2902 STp->timeout, MAX_RETRIES, 1); in osst_get_frame_position()
2904 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; in osst_get_frame_position()
2905 return (-EBUSY); in osst_get_frame_position()
2909 if (STp->buffer->syscall_result) in osst_get_frame_position()
2910 result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */ in osst_get_frame_position()
2912 if (result == -EINVAL) in osst_get_frame_position()
2915 if (result == -EIO) { /* re-read position - this needs to preserve media errors */ in osst_get_frame_position()
2917 memcpy (mysense, SRpnt->sense, 16); in osst_get_frame_position()
2920 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; in osst_get_frame_position()
2922 STp->timeout, MAX_RETRIES, 1); in osst_get_frame_position()
2925 name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:", in osst_get_frame_position()
2926 SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]); in osst_get_frame_position()
2928 if (!STp->buffer->syscall_result) in osst_get_frame_position()
2929 memcpy (SRpnt->sense, mysense, 16); in osst_get_frame_position()
2933 STp->first_frame_position = ((STp->buffer)->b_data[4] << 24) in osst_get_frame_position()
2934 + ((STp->buffer)->b_data[5] << 16) in osst_get_frame_position()
2935 + ((STp->buffer)->b_data[6] << 8) in osst_get_frame_position()
2936 + (STp->buffer)->b_data[7]; in osst_get_frame_position()
2937 STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24) in osst_get_frame_position()
2938 + ((STp->buffer)->b_data[ 9] << 16) in osst_get_frame_position()
2939 + ((STp->buffer)->b_data[10] << 8) in osst_get_frame_position()
2940 + (STp->buffer)->b_data[11]; in osst_get_frame_position()
2941 STp->cur_frames = (STp->buffer)->b_data[15]; in osst_get_frame_position()
2944 printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name, in osst_get_frame_position()
2945 STp->first_frame_position, STp->last_frame_position, in osst_get_frame_position()
2946 ((STp->buffer)->b_data[0]&0x80)?" (BOP)": in osst_get_frame_position()
2947 ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"", in osst_get_frame_position()
2948 STp->cur_frames); in osst_get_frame_position()
2951 if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) { in osst_get_frame_position()
2954 STp->first_frame_position, STp->last_frame_position, STp->cur_frames); in osst_get_frame_position()
2956 STp->first_frame_position = STp->last_frame_position; in osst_get_frame_position()
2959 STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; in osst_get_frame_position()
2961 return (result == 0 ? STp->first_frame_position : result); in osst_get_frame_position()
2975 if (STp->ready != ST_READY) return (-EIO); in osst_set_frame_position()
2977 STps = &(STp->ps[STp->partition]); in osst_set_frame_position()
2979 if (ppos < 0 || ppos > STp->capacity) { in osst_set_frame_position()
2981 pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1); in osst_set_frame_position()
2982 result = (-EINVAL); in osst_set_frame_position()
3000 SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout, in osst_set_frame_position()
3003 return (-EBUSY); in osst_set_frame_position()
3006 if ((STp->buffer)->syscall_result != 0) { in osst_set_frame_position()
3009 name, STp->first_frame_position, pp); in osst_set_frame_position()
3011 result = (-EIO); in osst_set_frame_position()
3016 STp->first_frame_position = STp->last_frame_position = ppos; in osst_set_frame_position()
3017 STps->eof = ST_NOEOF; in osst_set_frame_position()
3018 STps->at_sm = 0; in osst_set_frame_position()
3019 STps->rw = ST_IDLE; in osst_set_frame_position()
3020 STp->frame_in_buffer = 0; in osst_set_frame_position()
3026 struct st_partstat * STps = &(STp->ps[STp->partition]); in osst_write_trailer()
3029 if (STp->write_type != OS_WRITE_NEW_MARK) { in osst_write_trailer()
3036 if (STps->drv_file >= 0) in osst_write_trailer()
3037 STps->drv_file++ ; in osst_write_trailer()
3038 STps->drv_block = 0; in osst_write_trailer()
3043 STps->eof = ST_FM; in osst_write_trailer()
3048 /* osst versions of st functions - augmented and stripped to suit OnStream only */
3050 /* Flush the write buffer (never need to write if variable blocksize). */
3060 if ((STp->buffer)->writing) { in osst_flush_write_buffer()
3061 if (SRpnt == (STp->buffer)->last_SRpnt) in osst_flush_write_buffer()
3064 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name); in osst_flush_write_buffer()
3070 …"%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", n… in osst_flush_write_buffer()
3073 if ((STp->buffer)->syscall_result) { in osst_flush_write_buffer()
3077 name, (STp->buffer)->midlevel_result); in osst_flush_write_buffer()
3079 if ((STp->buffer)->midlevel_result == INT_MAX) in osst_flush_write_buffer()
3080 return (-ENOSPC); in osst_flush_write_buffer()
3081 return (-EIO); in osst_flush_write_buffer()
3086 if (STp->dirty == 1) { in osst_flush_write_buffer()
3088 STp->write_count++; in osst_flush_write_buffer()
3089 STps = &(STp->ps[STp->partition]); in osst_flush_write_buffer()
3090 STps->rw = ST_WRITING; in osst_flush_write_buffer()
3091 offset = STp->buffer->buffer_bytes; in osst_flush_write_buffer()
3092 blks = (offset + STp->block_size - 1) / STp->block_size; in osst_flush_write_buffer()
3096 osst_zero_buffer_tail(STp->buffer); in osst_flush_write_buffer()
3098 if (STp->poll) in osst_flush_write_buffer()
3099 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120)) in osst_flush_write_buffer()
3107 switch (STp->write_type) { in osst_flush_write_buffer()
3111 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", in osst_flush_write_buffer()
3112 name, blks, STp->frame_seq_number, in osst_flush_write_buffer()
3113 STp->logical_blk_num - blks, STp->logical_blk_num - 1); in osst_flush_write_buffer()
3115 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++, in osst_flush_write_buffer()
3116 STp->logical_blk_num - blks, STp->block_size, blks); in osst_flush_write_buffer()
3119 osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++, in osst_flush_write_buffer()
3120 STp->logical_blk_num, 0, 0); in osst_flush_write_buffer()
3123 osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++, in osst_flush_write_buffer()
3124 STp->logical_blk_num++, 0, blks=1); in osst_flush_write_buffer()
3139 STp->timeout, MAX_RETRIES, 1); in osst_flush_write_buffer()
3142 return (-EBUSY); in osst_flush_write_buffer()
3144 if ((STp->buffer)->syscall_result != 0) { in osst_flush_write_buffer()
3148 name, SRpnt->sense[0], SRpnt->sense[2], in osst_flush_write_buffer()
3149 SRpnt->sense[12], SRpnt->sense[13]); in osst_flush_write_buffer()
3151 if ((SRpnt->sense[0] & 0x70) == 0x70 && in osst_flush_write_buffer()
3152 (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */ in osst_flush_write_buffer()
3153 (SRpnt->sense[2] & 0x0f) == NO_SENSE) { in osst_flush_write_buffer()
3154 STp->dirty = 0; in osst_flush_write_buffer()
3155 (STp->buffer)->buffer_bytes = 0; in osst_flush_write_buffer()
3156 result = (-ENOSPC); in osst_flush_write_buffer()
3161 result = (-EIO); in osst_flush_write_buffer()
3164 STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */ in osst_flush_write_buffer()
3167 STp->first_frame_position++; in osst_flush_write_buffer()
3168 STp->dirty = 0; in osst_flush_write_buffer()
3169 (STp->buffer)->buffer_bytes = 0; in osst_flush_write_buffer()
3173 printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result); in osst_flush_write_buffer()
3179 /* Flush the tape buffer. The tape will be positioned correctly unless
3193 if( STp->pos_unknown) in osst_flush_buffer()
3194 return (-EIO); in osst_flush_buffer()
3196 if (STp->ready != ST_READY) in osst_flush_buffer()
3199 STps = &(STp->ps[STp->partition]); in osst_flush_buffer()
3200 if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */ in osst_flush_buffer()
3201 STp->write_type = OS_WRITE_DATA; in osst_flush_buffer()
3204 if (STp->block_size == 0) in osst_flush_buffer()
3208 printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name); in osst_flush_buffer()
3211 if (!STp->can_bsr) { in osst_flush_buffer()
3212 backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size - in osst_flush_buffer()
3213 ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ; in osst_flush_buffer()
3214 (STp->buffer)->buffer_bytes = 0; in osst_flush_buffer()
3215 (STp->buffer)->read_pointer = 0; in osst_flush_buffer()
3216 STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */ in osst_flush_buffer()
3220 if (STps->eof == ST_FM_HIT) { in osst_flush_buffer()
3223 STps->eof = ST_NOEOF; in osst_flush_buffer()
3225 if (STps->drv_file >= 0) in osst_flush_buffer()
3226 STps->drv_file++; in osst_flush_buffer()
3227 STps->drv_block = 0; in osst_flush_buffer()
3230 if (!result && backspace > 0) /* TODO -- design and run a test case for this */ in osst_flush_buffer()
3231 result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace); in osst_flush_buffer()
3233 else if (STps->eof == ST_FM_HIT) { in osst_flush_buffer()
3234 if (STps->drv_file >= 0) in osst_flush_buffer()
3235 STps->drv_file++; in osst_flush_buffer()
3236 STps->drv_block = 0; in osst_flush_buffer()
3237 STps->eof = ST_NOEOF; in osst_flush_buffer()
3252 if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */ in osst_write_frame()
3257 return (-EIO); in osst_write_frame()
3268 if (STp->poll) in osst_write_frame()
3269 if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120)) in osst_write_frame()
3271 return (-EIO); in osst_write_frame()
3275 STp->ps[STp->partition].rw = ST_WRITING; in osst_write_frame()
3276 STp->write_type = OS_WRITE_DATA; in osst_write_frame()
3281 cmd[4] = 1; /* one frame at a time... */ in osst_write_frame()
3282 blks = STp->buffer->buffer_bytes / STp->block_size; in osst_write_frame()
3285 printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks, in osst_write_frame()
3286 STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1); in osst_write_frame()
3288 osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++, in osst_write_frame()
3289 STp->logical_blk_num - blks, STp->block_size, blks); in osst_write_frame()
3293 STp->write_pending = 1; in osst_write_frame()
3295 SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout, in osst_write_frame()
3298 return (-EBUSY); in osst_write_frame()
3302 if (STp->buffer->syscall_result != 0) { in osst_write_frame()
3307 if ((SRpnt->sense[0] & 0x70) == 0x70 && in osst_write_frame()
3308 (SRpnt->sense[2] & 0x40)) { in osst_write_frame()
3309 if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW) in osst_write_frame()
3310 return (-ENOSPC); in osst_write_frame()
3314 return (-EIO); in osst_write_frame()
3318 STp->first_frame_position++; in osst_write_frame()
3321 STp->write_count++; in osst_write_frame()
3335 retval = scsi_ioctl(STp->device, cmd, NULL); in do_door_lock()
3337 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED; in do_door_lock()
3340 STp->door_locked = ST_LOCK_FAILS; in do_door_lock()
3351 STp->pos_unknown = 0; in reset_state()
3353 STps = &(STp->ps[i]); in reset_state()
3354 STps->rw = ST_IDLE; in reset_state()
3355 STps->eof = ST_NOEOF; in reset_state()
3356 STps->at_sm = 0; in reset_state()
3357 STps->last_block_valid = 0; in reset_state()
3358 STps->drv_block = -1; in reset_state()
3359 STps->drv_file = -1; in reset_state()
3377 struct osst_tape * STp = filp->private_data; in osst_write()
3381 if (mutex_lock_interruptible(&STp->lock)) in osst_write()
3382 return (-ERESTARTSYS); in osst_write()
3390 if( !scsi_block_when_processing_errors(STp->device) ) { in osst_write()
3391 retval = (-ENXIO); in osst_write()
3395 if (STp->ready != ST_READY) { in osst_write()
3396 if (STp->ready == ST_NO_TAPE) in osst_write()
3397 retval = (-ENOMEDIUM); in osst_write()
3399 retval = (-EIO); in osst_write()
3402 STm = &(STp->modes[STp->current_mode]); in osst_write()
3403 if (!STm->defined) { in osst_write()
3404 retval = (-ENXIO); in osst_write()
3414 if (STp->pos_unknown) { in osst_write()
3415 retval = (-EIO); in osst_write()
3420 if (!STp->in_use) { in osst_write()
3422 retval = (-EIO); in osst_write()
3427 if (STp->write_prot) { in osst_write()
3428 retval = (-EACCES); in osst_write()
3433 if (STp->block_size != 0 && (count % STp->block_size) != 0) { in osst_write()
3435 name, count, STp->block_size<1024? in osst_write()
3436 STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); in osst_write()
3437 retval = (-EINVAL); in osst_write()
3441 if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) { in osst_write()
3442 printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n", in osst_write()
3443 name, STp->first_frame_position); in osst_write()
3444 retval = (-ENOSPC); in osst_write()
3448 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1)) in osst_write()
3449 STp->door_locked = ST_LOCKED_AUTO; in osst_write()
3451 STps = &(STp->ps[STp->partition]); in osst_write()
3453 if (STps->rw == ST_READING) { in osst_write()
3456 STps->drv_file, STps->drv_block); in osst_write()
3461 STps->rw = ST_IDLE; in osst_write()
3463 if (STps->rw != ST_WRITING) { in osst_write()
3465 if (!STp->header_ok || in osst_write()
3466 (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) || in osst_write()
3467 (STps->drv_file == 0 && STps->drv_block == 0)) { in osst_write()
3468 STp->wrt_pass_cntr++; in osst_write()
3471 name, STp->wrt_pass_cntr); in osst_write()
3474 STps->drv_file = STps->drv_block = 0; in osst_write()
3478 if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) || in osst_write()
3479 STps->drv_file < 0 || STps->drv_block < 0) { in osst_write()
3480 if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */ in osst_write()
3481 STps->drv_file = STp->filemark_cnt; in osst_write()
3482 STps->drv_block = 0; in osst_write()
3485 /* We have no idea where the tape is positioned - give up */ in osst_write()
3490 retval = (-EIO); in osst_write()
3494 if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) { in osst_write()
3495 STp->filemark_cnt = STps->drv_file; in osst_write()
3496 STp->last_mark_ppos = in osst_write()
3497 ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]); in osst_write()
3500 name, STps->drv_file, STp->wrt_pass_cntr); in osst_write()
3507 name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn); in osst_write()
3511 STp->fast_open = 0; in osst_write()
3513 if (!STp->header_ok) { in osst_write()
3517 retval = (-EIO); in osst_write()
3521 if ((STp->buffer)->writing) { in osst_write()
3524 if ((STp->buffer)->syscall_result) { in osst_write()
3528 (STp->buffer)->midlevel_result); in osst_write()
3530 if ((STp->buffer)->midlevel_result == INT_MAX) in osst_write()
3531 STps->eof = ST_EOM_OK; in osst_write()
3533 STps->eof = ST_EOM_ERROR; in osst_write()
3536 if (STps->eof == ST_EOM_OK) { in osst_write()
3537 retval = (-ENOSPC); in osst_write()
3540 else if (STps->eof == ST_EOM_ERROR) { in osst_write()
3541 retval = (-EIO); in osst_write()
3545 /* Check the buffer readability in cases where copy_user might catch in osst_write()
3548 copy_from_user(&i, buf + count - 1, 1) != 0)) { in osst_write()
3549 retval = (-EFAULT); in osst_write()
3553 if (!STm->do_buffer_writes) { in osst_write()
3557 write_threshold = (STp->buffer)->buffer_blocks * STp->block_size; in osst_write()
3558 if (!STm->do_async_writes) in osst_write()
3559 write_threshold--; in osst_write()
3565 name, (int) count, STps->drv_file, STps->drv_block, in osst_write()
3566 STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position); in osst_write()
3569 while ((STp->buffer)->buffer_bytes + count > write_threshold) in osst_write()
3572 do_count = (STp->buffer)->buffer_blocks * STp->block_size - in osst_write()
3573 (STp->buffer)->buffer_bytes; in osst_write()
3577 i = append_to_buffer(b_point, STp->buffer, do_count); in osst_write()
3583 blks = do_count / STp->block_size; in osst_write()
3584 STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */ in osst_write()
3588 if (i == (-ENOSPC)) { in osst_write()
3589 transfer = STp->buffer->writing; /* FIXME -- check this logic */ in osst_write()
3591 *ppos += do_count - transfer; in osst_write()
3592 count -= do_count - transfer; in osst_write()
3593 if (STps->drv_block >= 0) { in osst_write()
3594 STps->drv_block += (do_count - transfer) / STp->block_size; in osst_write()
3596 STps->eof = ST_EOM_OK; in osst_write()
3597 retval = (-ENOSPC); /* EOM within current request */ in osst_write()
3605 STps->eof = ST_EOM_ERROR; in osst_write()
3606 STps->drv_block = (-1); /* Too cautious? */ in osst_write()
3607 retval = (-EIO); /* EOM for old data */ in osst_write()
3622 STp->buffer->buffer_bytes = 0; in osst_write()
3623 STp->dirty = 0; in osst_write()
3625 retval = total - count; in osst_write()
3631 count -= do_count; in osst_write()
3632 if (STps->drv_block >= 0) { in osst_write()
3633 STps->drv_block += blks; in osst_write()
3635 STp->buffer->buffer_bytes = 0; in osst_write()
3636 STp->dirty = 0; in osst_write()
3640 STp->dirty = 1; in osst_write()
3641 i = append_to_buffer(b_point, STp->buffer, count); in osst_write()
3646 blks = count / STp->block_size; in osst_write()
3647 STp->logical_blk_num += blks; in osst_write()
3648 if (STps->drv_block >= 0) { in osst_write()
3649 STps->drv_block += blks; in osst_write()
3655 if (doing_write && (STp->buffer)->syscall_result != 0) { in osst_write()
3656 retval = (STp->buffer)->syscall_result; in osst_write()
3660 if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) { in osst_write()
3662 (STp->buffer)->writing = ((STp->buffer)->buffer_bytes / in osst_write()
3663 STp->block_size) * STp->block_size; in osst_write()
3664 STp->dirty = !((STp->buffer)->writing == in osst_write()
3665 (STp->buffer)->buffer_bytes); in osst_write()
3669 retval = (-EIO); in osst_write()
3674 STps->at_sm &= (total == 0); in osst_write()
3676 STps->eof = ST_NOEOF; in osst_write()
3683 mutex_unlock(&STp->lock); in osst_write()
3698 struct osst_tape * STp = filp->private_data; in osst_read()
3702 if (mutex_lock_interruptible(&STp->lock)) in osst_read()
3703 return (-ERESTARTSYS); in osst_read()
3711 if( !scsi_block_when_processing_errors(STp->device) ) { in osst_read()
3712 retval = (-ENXIO); in osst_read()
3716 if (STp->ready != ST_READY) { in osst_read()
3717 if (STp->ready == ST_NO_TAPE) in osst_read()
3718 retval = (-ENOMEDIUM); in osst_read()
3720 retval = (-EIO); in osst_read()
3723 STm = &(STp->modes[STp->current_mode]); in osst_read()
3724 if (!STm->defined) { in osst_read()
3725 retval = (-ENXIO); in osst_read()
3729 if (!STp->in_use) { in osst_read()
3731 retval = (-EIO); in osst_read()
3736 if (!STp->header_ok) { in osst_read()
3737 retval = (-EIO); in osst_read()
3741 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1)) in osst_read()
3742 STp->door_locked = ST_LOCKED_AUTO; in osst_read()
3744 STps = &(STp->ps[STp->partition]); in osst_read()
3745 if (STps->rw == ST_WRITING) { in osst_read()
3749 STps->rw = ST_IDLE; in osst_read()
3750 /* FIXME -- this may leave the tape without EOD and up2date headers */ in osst_read()
3753 if ((count % STp->block_size) != 0) { in osst_read()
3756 STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); in osst_read()
3760 if (debugging && STps->eof != ST_NOEOF) in osst_read()
3762 STps->eof, (STp->buffer)->buffer_bytes); in osst_read()
3764 if ((STp->buffer)->buffer_bytes == 0 && in osst_read()
3765 STps->eof >= ST_EOD_1) { in osst_read()
3766 if (STps->eof < ST_EOD) { in osst_read()
3767 STps->eof += 1; in osst_read()
3771 retval = (-EIO); /* EOM or Blank Check */ in osst_read()
3775 /* Check the buffer writability before any tape movement. Don't alter in osst_read()
3776 buffer data. */ in osst_read()
3779 copy_from_user(&i, buf + count - 1, 1) != 0 || in osst_read()
3780 copy_to_user (buf + count - 1, &i, 1) != 0) { in osst_read()
3781 retval = (-EFAULT); in osst_read()
3785 /* Loop until enough data in buffer or a special condition found */ in osst_read()
3786 for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) { in osst_read()
3788 /* Get new data if the buffer is empty */ in osst_read()
3789 if ((STp->buffer)->buffer_bytes == 0) { in osst_read()
3790 if (STps->eof == ST_FM_HIT) in osst_read()
3792 special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0); in osst_read()
3794 STp->frame_in_buffer = 0; in osst_read()
3800 /* Move the data from driver buffer to user buffer */ in osst_read()
3801 if ((STp->buffer)->buffer_bytes > 0) { in osst_read()
3803 if (debugging && STps->eof != ST_NOEOF) in osst_read()
3805 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total)); in osst_read()
3808 transfer = (((STp->buffer)->buffer_bytes < count - total ? in osst_read()
3809 (STp->buffer)->buffer_bytes : count - total)/ in osst_read()
3810 STp->block_size) * STp->block_size; in osst_read()
3815 name, count, STp->block_size < 1024? in osst_read()
3816 STp->block_size:STp->block_size/1024, in osst_read()
3817 STp->block_size<1024?'b':'k'); in osst_read()
3820 i = from_buffer(STp->buffer, buf, transfer); in osst_read()
3825 STp->logical_blk_num += transfer / STp->block_size; in osst_read()
3826 STps->drv_block += transfer / STp->block_size; in osst_read()
3832 if ((STp->buffer)->buffer_bytes == 0) { in osst_read()
3835 printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n", in osst_read()
3836 name, STp->frame_seq_number); in osst_read()
3838 STp->frame_in_buffer = 0; in osst_read()
3839 STp->frame_seq_number++; /* frame to look for next time */ in osst_read()
3843 /* Change the eof state if no data from tape or buffer */ in osst_read()
3845 if (STps->eof == ST_FM_HIT) { in osst_read()
3846 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM; in osst_read()
3847 STps->drv_block = 0; in osst_read()
3848 if (STps->drv_file >= 0) in osst_read()
3849 STps->drv_file++; in osst_read()
3851 else if (STps->eof == ST_EOD_1) { in osst_read()
3852 STps->eof = ST_EOD_2; in osst_read()
3853 if (STps->drv_block > 0 && STps->drv_file >= 0) in osst_read()
3854 STps->drv_file++; in osst_read()
3855 STps->drv_block = 0; in osst_read()
3857 else if (STps->eof == ST_EOD_2) in osst_read()
3858 STps->eof = ST_EOD; in osst_read()
3860 else if (STps->eof == ST_FM) in osst_read()
3861 STps->eof = ST_NOEOF; in osst_read()
3868 mutex_unlock(&STp->lock); in osst_read()
3878 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n", in osst_log_options()
3879 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes, in osst_log_options()
3880 STm->do_read_ahead); in osst_log_options()
3883 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock); in osst_log_options()
3886 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, in osst_log_options()
3887 STp->scsi2_logical); in osst_log_options()
3889 "%s:I: sysv: %d\n", name, STm->sysv); in osst_log_options()
3905 STm = &(STp->modes[STp->current_mode]); in osst_set_options()
3906 if (!STm->defined) { in osst_set_options()
3907 memcpy(STm, &(STp->modes[0]), sizeof(*STm)); in osst_set_options()
3912 name, STp->current_mode); in osst_set_options()
3918 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0; in osst_set_options()
3919 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0; in osst_set_options()
3920 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0; in osst_set_options()
3921 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0; in osst_set_options()
3922 STp->two_fm = (options & MT_ST_TWO_FM) != 0; in osst_set_options()
3923 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0; in osst_set_options()
3924 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0; in osst_set_options()
3925 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0; in osst_set_options()
3926 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0; in osst_set_options()
3927 if ((STp->device)->scsi_level >= SCSI_2) in osst_set_options()
3928 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0; in osst_set_options()
3929 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; in osst_set_options()
3930 STm->sysv = (options & MT_ST_SYSV) != 0; in osst_set_options()
3939 STm->do_buffer_writes = value; in osst_set_options()
3941 STm->do_async_writes = value; in osst_set_options()
3943 STm->defaults_for_writes = value; in osst_set_options()
3945 STm->do_read_ahead = value; in osst_set_options()
3947 STp->two_fm = value; in osst_set_options()
3949 STp->fast_mteom = value; in osst_set_options()
3951 STp->do_auto_lock = value; in osst_set_options()
3953 STp->can_bsr = value; in osst_set_options()
3955 STp->omit_blklims = value; in osst_set_options()
3956 if ((STp->device)->scsi_level >= SCSI_2 && in osst_set_options()
3958 STp->can_partitions = value; in osst_set_options()
3960 STp->scsi2_logical = value; in osst_set_options()
3962 STm->sysv = value; in osst_set_options()
3974 return (-EIO); in osst_set_options()
3976 STp->write_threshold = value; in osst_set_options()
3983 STm->default_blksize = (-1); in osst_set_options()
3990 return (-EINVAL); in osst_set_options()
3992 STm->default_blksize = value; in osst_set_options()
3994 name, STm->default_blksize); in osst_set_options()
4000 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ; in osst_set_options()
4005 STp->timeout = value * HZ; in osst_set_options()
4014 STm->default_density = (-1); in osst_set_options()
4018 STm->default_density = value & 0xff; in osst_set_options()
4020 name, STm->default_density); in osst_set_options()
4025 STp->default_drvbuffer = 0xff; in osst_set_options()
4026 printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name); in osst_set_options()
4029 STp->default_drvbuffer = value & 7; in osst_set_options()
4030 printk(KERN_INFO "%s:I: Drive buffer default set to %x\n", in osst_set_options()
4031 name, STp->default_drvbuffer); in osst_set_options()
4036 STm->default_compression = ST_DONT_TOUCH; in osst_set_options()
4040 STm->default_compression = (value & 1 ? ST_YES : ST_NO); in osst_set_options()
4047 return (-EIO); in osst_set_options()
4068 if (STp->ready != ST_READY && cmd_in != MTLOAD) { in osst_int_ioctl()
4069 if (STp->ready == ST_NO_TAPE) in osst_int_ioctl()
4070 return (-ENOMEDIUM); in osst_int_ioctl()
4072 return (-EIO); in osst_int_ioctl()
4074 timeout = STp->long_timeout; in osst_int_ioctl()
4075 STps = &(STp->ps[STp->partition]); in osst_int_ioctl()
4076 fileno = STps->drv_file; in osst_int_ioctl()
4077 blkno = STps->drv_block; in osst_int_ioctl()
4078 at_sm = STps->at_sm; in osst_int_ioctl()
4079 frame_seq_numbr = STp->frame_seq_number; in osst_int_ioctl()
4080 logical_blk_num = STp->logical_blk_num; in osst_int_ioctl()
4087 if (STp->raw) in osst_int_ioctl()
4088 return (-EIO); in osst_int_ioctl()
4089 if (STp->linux_media) in osst_int_ioctl()
4102 if (STp->raw) in osst_int_ioctl()
4103 return (-EIO); in osst_int_ioctl()
4106 fileno -= arg; in osst_int_ioctl()
4107 blkno = (-1); /* We can't know the block number */ in osst_int_ioctl()
4123 logical_blk_num -= arg; in osst_int_ioctl()
4124 if (blkno >= 0) blkno -= arg; in osst_int_ioctl()
4127 fileno = STps->drv_file; in osst_int_ioctl()
4128 blkno = STps->drv_block; in osst_int_ioctl()
4134 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */ in osst_int_ioctl()
4144 blkno = fileno = (-1); in osst_int_ioctl()
4150 cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */ in osst_int_ioctl()
4151 ltmp = (-arg); in osst_int_ioctl()
4161 name, (-ltmp)); in osst_int_ioctl()
4165 blkno = fileno = (-1); in osst_int_ioctl()
4170 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) { in osst_int_ioctl()
4171 STp->write_type = OS_WRITE_DATA; in osst_int_ioctl()
4186 if (STp->write_prot) in osst_int_ioctl()
4187 return (-EACCES); in osst_int_ioctl()
4188 if (!STp->raw) in osst_int_ioctl()
4190 cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */ in osst_int_ioctl()
4196 timeout = STp->timeout; in osst_int_ioctl()
4214 if (STp->ready == ST_NO_TAPE) in osst_int_ioctl()
4223 timeout = STp->timeout; in osst_int_ioctl()
4247 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name); in osst_int_ioctl()
4256 if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) || in osst_int_ioctl()
4257 (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) { in osst_int_ioctl()
4258 ioctl_result = -EIO; in osst_int_ioctl()
4261 if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) { in osst_int_ioctl()
4263 printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name); in osst_int_ioctl()
4265 ioctl_result = -EIO; in osst_int_ioctl()
4268 ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0); in osst_int_ioctl()
4269 fileno = STp->filemark_cnt; in osst_int_ioctl()
4274 if (STp->write_prot) in osst_int_ioctl()
4275 return (-EACCES); in osst_int_ioctl()
4279 i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos); in osst_int_ioctl()
4295 if ((STps->drv_block == 0 ) && in osst_int_ioctl()
4296 !STp->dirty && in osst_int_ioctl()
4297 ((STp->buffer)->buffer_bytes == 0) && in osst_int_ioctl()
4307 STp->block_size = (arg & MT_ST_BLKSIZE_MASK); in osst_int_ioctl()
4309 name, STp->block_size); in osst_int_ioctl()
4316 if (STp->dirty || (STp->buffer)->buffer_bytes != 0) in osst_int_ioctl()
4317 return (-EIO); /* Not allowed if data in buffer */ in osst_int_ioctl()
4320 (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) { in osst_int_ioctl()
4324 return (-EINVAL); in osst_int_ioctl()
4329 return (-ENOSYS); in osst_int_ioctl()
4334 ioctl_result = (STp->buffer)->syscall_result; in osst_int_ioctl()
4344 STp->frame_seq_number = frame_seq_numbr; in osst_int_ioctl()
4345 STp->logical_blk_num = logical_blk_num; in osst_int_ioctl()
4357 fileno--; in osst_int_ioctl()
4358 blkno--; in osst_int_ioctl()
4364 STps->drv_block = blkno; in osst_int_ioctl()
4365 STps->drv_file = fileno; in osst_int_ioctl()
4366 STps->at_sm = at_sm; in osst_int_ioctl()
4369 STps->eof = ST_EOD; in osst_int_ioctl()
4370 else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) { in osst_int_ioctl()
4371 ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1); in osst_int_ioctl()
4372 STps->drv_block++; in osst_int_ioctl()
4373 STp->logical_blk_num++; in osst_int_ioctl()
4374 STp->frame_seq_number++; in osst_int_ioctl()
4375 STp->frame_in_buffer = 0; in osst_int_ioctl()
4376 STp->buffer->read_pointer = 0; in osst_int_ioctl()
4379 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM; in osst_int_ioctl()
4381 STps->eof = ST_NOEOF; in osst_int_ioctl()
4384 STp->rew_at_close = 0; in osst_int_ioctl()
4387 STp->ps[i].rw = ST_IDLE; in osst_int_ioctl()
4388 STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */ in osst_int_ioctl()
4390 STp->partition = 0; in osst_int_ioctl()
4394 ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos); in osst_int_ioctl()
4400 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0) in osst_int_ioctl()
4401 STps->drv_file = STps->drv_block = -1; in osst_int_ioctl()
4403 STps->drv_file = STps->drv_block = 0; in osst_int_ioctl()
4404 STps->eof = ST_NOEOF; in osst_int_ioctl()
4406 if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) in osst_int_ioctl()
4407 STps->drv_file = STps->drv_block = -1; in osst_int_ioctl()
4409 STps->drv_file = STp->filemark_cnt; in osst_int_ioctl()
4410 STps->drv_block = 0; in osst_int_ioctl()
4412 STps->eof = ST_EOD; in osst_int_ioctl()
4414 STps->drv_file = STps->drv_block = (-1); in osst_int_ioctl()
4415 STps->eof = ST_NOEOF; in osst_int_ioctl()
4416 STp->header_ok = 0; in osst_int_ioctl()
4418 STp->header_ok = 0; in osst_int_ioctl()
4420 if (SRpnt->sense[2] & 0x40) { in osst_int_ioctl()
4421 STps->eof = ST_EOM_OK; in osst_int_ioctl()
4422 STps->drv_block = 0; in osst_int_ioctl()
4425 STps->eof = ST_NOEOF; in osst_int_ioctl()
4427 if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK) in osst_int_ioctl()
4428 STps->eof = ST_EOD; in osst_int_ioctl()
4458 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); in __os_scsi_tape_open()
4462 (STp = os_scsi_tapes[dev]) == NULL || !STp->device) { in __os_scsi_tape_open()
4464 return (-ENXIO); in __os_scsi_tape_open()
4469 if (STp->in_use) { in __os_scsi_tape_open()
4474 return (-EBUSY); in __os_scsi_tape_open()
4476 if (scsi_device_get(STp->device)) { in __os_scsi_tape_open()
4481 return (-ENXIO); in __os_scsi_tape_open()
4483 filp->private_data = STp; in __os_scsi_tape_open()
4484 STp->in_use = 1; in __os_scsi_tape_open()
4486 STp->rew_at_close = TAPE_REWIND(inode); in __os_scsi_tape_open()
4488 if( !scsi_block_when_processing_errors(STp->device) ) { in __os_scsi_tape_open()
4489 return -ENXIO; in __os_scsi_tape_open()
4492 if (mode != STp->current_mode) { in __os_scsi_tape_open()
4496 name, STp->current_mode, mode); in __os_scsi_tape_open()
4499 STp->current_mode = mode; in __os_scsi_tape_open()
4501 STm = &(STp->modes[STp->current_mode]); in __os_scsi_tape_open()
4503 flags = filp->f_flags; in __os_scsi_tape_open()
4504 STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY); in __os_scsi_tape_open()
4506 STp->raw = TAPE_IS_RAW(inode); in __os_scsi_tape_open()
4507 if (STp->raw) in __os_scsi_tape_open()
4508 STp->header_ok = 0; in __os_scsi_tape_open()
4510 /* Allocate data segments for this device's tape buffer */ in __os_scsi_tape_open()
4511 if (!enlarge_buffer(STp->buffer, STp->restr_dma)) { in __os_scsi_tape_open()
4512 printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name); in __os_scsi_tape_open()
4513 retval = (-EOVERFLOW); in __os_scsi_tape_open()
4516 if (STp->buffer->buffer_size >= OS_FRAME_SIZE) { in __os_scsi_tape_open()
4518 (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); in __os_scsi_tape_open()
4519 b_size += STp->buffer->sg[i++].length); in __os_scsi_tape_open()
4520 …STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_siz… in __os_scsi_tape_open()
4523 STp->buffer->b_data, page_address(STp->buffer->sg[0].page)); in __os_scsi_tape_open()
4525 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page)); in __os_scsi_tape_open()
4528 STp->buffer->aux = NULL; /* this had better never happen! */ in __os_scsi_tape_open()
4529 printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE); in __os_scsi_tape_open()
4530 retval = (-EIO); in __os_scsi_tape_open()
4533 STp->buffer->writing = 0; in __os_scsi_tape_open()
4534 STp->buffer->syscall_result = 0; in __os_scsi_tape_open()
4535 STp->dirty = 0; in __os_scsi_tape_open()
4537 STps = &(STp->ps[i]); in __os_scsi_tape_open()
4538 STps->rw = ST_IDLE; in __os_scsi_tape_open()
4540 STp->ready = ST_READY; in __os_scsi_tape_open()
4542 STp->nbr_waits = STp->nbr_finished = 0; in __os_scsi_tape_open()
4548 SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); in __os_scsi_tape_open()
4550 retval = (STp->buffer)->syscall_result; /* FIXME - valid? */ in __os_scsi_tape_open()
4553 if ((SRpnt->sense[0] & 0x70) == 0x70 && in __os_scsi_tape_open()
4554 (SRpnt->sense[2] & 0x0f) == NOT_READY && in __os_scsi_tape_open()
4555 SRpnt->sense[12] == 4 ) { in __os_scsi_tape_open()
4557 printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]); in __os_scsi_tape_open()
4559 if (filp->f_flags & O_NONBLOCK) { in __os_scsi_tape_open()
4560 retval = -EAGAIN; in __os_scsi_tape_open()
4563 if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */ in __os_scsi_tape_open()
4569 STp->timeout, MAX_RETRIES, 1); in __os_scsi_tape_open()
4571 osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0); in __os_scsi_tape_open()
4573 if ((SRpnt->sense[0] & 0x70) == 0x70 && in __os_scsi_tape_open()
4574 (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */ in __os_scsi_tape_open()
4578 STp->header_ok = 0; in __os_scsi_tape_open()
4586 STp->timeout, MAX_RETRIES, 1); in __os_scsi_tape_open()
4587 if ((SRpnt->sense[0] & 0x70) != 0x70 || in __os_scsi_tape_open()
4588 (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION) in __os_scsi_tape_open()
4592 STp->pos_unknown = 0; in __os_scsi_tape_open()
4593 STp->partition = STp->new_partition = 0; in __os_scsi_tape_open()
4594 if (STp->can_partitions) in __os_scsi_tape_open()
4595 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ in __os_scsi_tape_open()
4597 STps = &(STp->ps[i]); in __os_scsi_tape_open()
4598 STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */ in __os_scsi_tape_open()
4599 STps->eof = ST_NOEOF; in __os_scsi_tape_open()
4600 STps->at_sm = 0; in __os_scsi_tape_open()
4601 STps->last_block_valid = 0; in __os_scsi_tape_open()
4602 STps->drv_block = 0; in __os_scsi_tape_open()
4603 STps->drv_file = 0 ; in __os_scsi_tape_open()
4606 STp->recover_count = 0; in __os_scsi_tape_open()
4607 STp->abort_count = 0; in __os_scsi_tape_open()
4611 * open without reconfiguring and re-reading the headers in __os_scsi_tape_open()
4613 if (!STp->buffer->syscall_result && STp->header_ok && in __os_scsi_tape_open()
4614 !SRpnt->result && SRpnt->sense[0] == 0) { in __os_scsi_tape_open()
4622 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); in __os_scsi_tape_open()
4624 if (STp->buffer->syscall_result || in __os_scsi_tape_open()
4625 STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' || in __os_scsi_tape_open()
4626 STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' || in __os_scsi_tape_open()
4627 STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' || in __os_scsi_tape_open()
4628 STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) { in __os_scsi_tape_open()
4631 STp->buffer->b_data[MODE_HEADER_LENGTH + 2], in __os_scsi_tape_open()
4632 STp->buffer->b_data[MODE_HEADER_LENGTH + 3], in __os_scsi_tape_open()
4633 STp->buffer->b_data[MODE_HEADER_LENGTH + 4], in __os_scsi_tape_open()
4634 STp->buffer->b_data[MODE_HEADER_LENGTH + 5]); in __os_scsi_tape_open()
4636 STp->header_ok = 0; in __os_scsi_tape_open()
4638 i = STp->first_frame_position; in __os_scsi_tape_open()
4639 if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) { in __os_scsi_tape_open()
4640 if (STp->door_locked == ST_UNLOCKED) { in __os_scsi_tape_open()
4644 STp->door_locked = ST_LOCKED_AUTO; in __os_scsi_tape_open()
4646 if (!STp->frame_in_buffer) { in __os_scsi_tape_open()
4647 STp->block_size = (STm->default_blksize > 0) ? in __os_scsi_tape_open()
4648 STm->default_blksize : OS_DATA_SIZE; in __os_scsi_tape_open()
4649 STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0; in __os_scsi_tape_open()
4651 STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size; in __os_scsi_tape_open()
4652 STp->fast_open = 1; in __os_scsi_tape_open()
4657 if (i != STp->first_frame_position) in __os_scsi_tape_open()
4659 name, i, STp->first_frame_position); in __os_scsi_tape_open()
4661 STp->header_ok = 0; in __os_scsi_tape_open()
4663 STp->fast_open = 0; in __os_scsi_tape_open()
4665 if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */ in __os_scsi_tape_open()
4666 (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) { in __os_scsi_tape_open()
4673 (STp->buffer)->b_data[0] = cmd[4] - 1; in __os_scsi_tape_open()
4674 (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */ in __os_scsi_tape_open()
4675 (STp->buffer)->b_data[2] = 0; /* Reserved */ in __os_scsi_tape_open()
4676 (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */ in __os_scsi_tape_open()
4677 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f; in __os_scsi_tape_open()
4678 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1; in __os_scsi_tape_open()
4679 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2; in __os_scsi_tape_open()
4680 (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3; in __os_scsi_tape_open()
4685 SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); in __os_scsi_tape_open()
4687 STp->header_ok = 0; in __os_scsi_tape_open()
4695 STp->timeout, MAX_RETRIES, 1); in __os_scsi_tape_open()
4696 if ((SRpnt->sense[0] & 0x70) != 0x70 || in __os_scsi_tape_open()
4697 (SRpnt->sense[2] & 0x0f) == NOT_READY) in __os_scsi_tape_open()
4700 if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { in __os_scsi_tape_open()
4703 STp->pos_unknown = 0; in __os_scsi_tape_open()
4704 STp->partition = STp->new_partition = 0; in __os_scsi_tape_open()
4705 if (STp->can_partitions) in __os_scsi_tape_open()
4706 STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ in __os_scsi_tape_open()
4708 STps = &(STp->ps[j]); in __os_scsi_tape_open()
4709 STps->rw = ST_IDLE; in __os_scsi_tape_open()
4710 STps->eof = ST_NOEOF; in __os_scsi_tape_open()
4711 STps->at_sm = 0; in __os_scsi_tape_open()
4712 STps->last_block_valid = 0; in __os_scsi_tape_open()
4713 STps->drv_block = 0; in __os_scsi_tape_open()
4714 STps->drv_file = 0 ; in __os_scsi_tape_open()
4721 if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */ in __os_scsi_tape_open()
4724 if ((STp->buffer)->syscall_result != 0) { in __os_scsi_tape_open()
4725 if ((STp->device)->scsi_level >= SCSI_2 && in __os_scsi_tape_open()
4726 (SRpnt->sense[0] & 0x70) == 0x70 && in __os_scsi_tape_open()
4727 (SRpnt->sense[2] & 0x0f) == NOT_READY && in __os_scsi_tape_open()
4728 SRpnt->sense[12] == 0x3a) { /* Check ASC */ in __os_scsi_tape_open()
4729 STp->ready = ST_NO_TAPE; in __os_scsi_tape_open()
4731 STp->ready = ST_NOT_READY; in __os_scsi_tape_open()
4734 STp->density = 0; /* Clear the erroneous "residue" */ in __os_scsi_tape_open()
4735 STp->write_prot = 0; in __os_scsi_tape_open()
4736 STp->block_size = 0; in __os_scsi_tape_open()
4737 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1); in __os_scsi_tape_open()
4738 STp->partition = STp->new_partition = 0; in __os_scsi_tape_open()
4739 STp->door_locked = ST_UNLOCKED; in __os_scsi_tape_open()
4745 STp->block_size = STp->raw ? OS_FRAME_SIZE : ( in __os_scsi_tape_open()
4746 (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE); in __os_scsi_tape_open()
4747 STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size; in __os_scsi_tape_open()
4748 STp->buffer->buffer_bytes = in __os_scsi_tape_open()
4749 STp->buffer->read_pointer = in __os_scsi_tape_open()
4750 STp->frame_in_buffer = 0; in __os_scsi_tape_open()
4754 printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n", in __os_scsi_tape_open()
4755 name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size, in __os_scsi_tape_open()
4756 (STp->buffer)->buffer_blocks); in __os_scsi_tape_open()
4759 if (STp->drv_write_prot) { in __os_scsi_tape_open()
4760 STp->write_prot = 1; in __os_scsi_tape_open()
4766 retval = (-EROFS); in __os_scsi_tape_open()
4776 STp->density_changed = STp->blksize_changed = 0; in __os_scsi_tape_open()
4777 STp->compression_changed = 0; in __os_scsi_tape_open()
4783 if (STp->door_locked == ST_UNLOCKED) { in __os_scsi_tape_open()
4787 STp->door_locked = ST_LOCKED_AUTO; in __os_scsi_tape_open()
4800 normalize_buffer(STp->buffer); in __os_scsi_tape_open()
4801 STp->header_ok = 0; in __os_scsi_tape_open()
4802 STp->in_use = 0; in __os_scsi_tape_open()
4803 scsi_device_put(STp->device); in __os_scsi_tape_open()
4821 /* Flush the tape buffer before close */
4825 struct osst_tape * STp = filp->private_data; in os_scsi_tape_flush()
4826 struct st_modedef * STm = &(STp->modes[STp->current_mode]); in os_scsi_tape_flush()
4827 struct st_partstat * STps = &(STp->ps[STp->partition]); in os_scsi_tape_flush()
4834 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) { in os_scsi_tape_flush()
4835 STp->write_type = OS_WRITE_DATA; in os_scsi_tape_flush()
4837 if (result != 0 && result != (-ENOSPC)) in os_scsi_tape_flush()
4840 if ( STps->rw >= ST_WRITING && !STp->pos_unknown) { in os_scsi_tape_flush()
4845 name, (long)(filp->f_pos)); in os_scsi_tape_flush()
4847 name, STp->nbr_waits, STp->nbr_finished); in os_scsi_tape_flush()
4850 result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close)); in os_scsi_tape_flush()
4853 printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n", in os_scsi_tape_flush()
4854 name, 1+STp->two_fm); in os_scsi_tape_flush()
4857 else if (!STp->rew_at_close) { in os_scsi_tape_flush()
4858 STps = &(STp->ps[STp->partition]); in os_scsi_tape_flush()
4859 if (!STm->sysv || STps->rw != ST_READING) { in os_scsi_tape_flush()
4860 if (STp->can_bsr) in os_scsi_tape_flush()
4862 else if (STps->eof == ST_FM_HIT) { in os_scsi_tape_flush()
4865 if (STps->drv_file >= 0) in os_scsi_tape_flush()
4866 STps->drv_file++; in os_scsi_tape_flush()
4867 STps->drv_block = 0; in os_scsi_tape_flush()
4868 STps->eof = ST_FM; in os_scsi_tape_flush()
4871 STps->eof = ST_NOEOF; in os_scsi_tape_flush()
4874 else if ((STps->eof == ST_NOEOF && in os_scsi_tape_flush()
4876 STps->eof == ST_FM_HIT) { in os_scsi_tape_flush()
4877 if (STps->drv_file >= 0) in os_scsi_tape_flush()
4878 STps->drv_file++; in os_scsi_tape_flush()
4879 STps->drv_block = 0; in os_scsi_tape_flush()
4880 STps->eof = ST_FM; in os_scsi_tape_flush()
4885 if (STp->rew_at_close) { in os_scsi_tape_flush()
4886 result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos); in os_scsi_tape_flush()
4887 STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0; in os_scsi_tape_flush()
4893 if (STp->abort_count || STp->recover_count) { in os_scsi_tape_flush()
4895 if (STp->abort_count) in os_scsi_tape_flush()
4896 printk(" %d unrecovered errors", STp->abort_count); in os_scsi_tape_flush()
4897 if (STp->recover_count) in os_scsi_tape_flush()
4898 printk(" %d recovered errors", STp->recover_count); in os_scsi_tape_flush()
4899 if (STp->write_count) in os_scsi_tape_flush()
4900 printk(" in %d frames written", STp->write_count); in os_scsi_tape_flush()
4901 if (STp->read_count) in os_scsi_tape_flush()
4902 printk(" in %d frames read", STp->read_count); in os_scsi_tape_flush()
4904 STp->recover_count = 0; in os_scsi_tape_flush()
4905 STp->abort_count = 0; in os_scsi_tape_flush()
4907 STp->write_count = 0; in os_scsi_tape_flush()
4908 STp->read_count = 0; in os_scsi_tape_flush()
4918 struct osst_tape * STp = filp->private_data; in os_scsi_tape_close()
4920 if (STp->door_locked == ST_LOCKED_AUTO) in os_scsi_tape_close()
4923 if (STp->raw) in os_scsi_tape_close()
4924 STp->header_ok = 0; in os_scsi_tape_close()
4926 normalize_buffer(STp->buffer); in os_scsi_tape_close()
4928 STp->in_use = 0; in os_scsi_tape_close()
4931 scsi_device_put(STp->device); in os_scsi_tape_close()
4945 struct osst_tape * STp = file->private_data; in osst_ioctl()
4950 if (mutex_lock_interruptible(&STp->lock)) { in osst_ioctl()
4952 return -ERESTARTSYS; in osst_ioctl()
4956 if (debugging && !STp->in_use) { in osst_ioctl()
4958 retval = (-EIO); in osst_ioctl()
4962 STm = &(STp->modes[STp->current_mode]); in osst_ioctl()
4963 STps = &(STp->ps[STp->partition]); in osst_ioctl()
4971 if( !scsi_block_when_processing_errors(STp->device) ) { in osst_ioctl()
4972 retval = (-ENXIO); in osst_ioctl()
4980 cmd_type, cmd_nr, STp->raw?"raw":"normal"); in osst_ioctl()
4987 retval = (-EINVAL); in osst_ioctl()
4993 retval = (-EFAULT); in osst_ioctl()
4999 retval = (-EPERM); in osst_ioctl()
5003 if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) { in osst_ioctl()
5004 retval = (-ENXIO); in osst_ioctl()
5008 if (!STp->pos_unknown) { in osst_ioctl()
5010 if (STps->eof == ST_FM_HIT) { in osst_ioctl()
5012 mtc.mt_count -= 1; in osst_ioctl()
5013 if (STps->drv_file >= 0) in osst_ioctl()
5014 STps->drv_file += 1; in osst_ioctl()
5018 if (STps->drv_file >= 0) in osst_ioctl()
5019 STps->drv_file += 1; in osst_ioctl()
5025 i = !STp->can_partitions || (STp->new_partition != STp->partition); in osst_ioctl()
5053 retval = (-EIO); in osst_ioctl()
5058 STp->device->was_reset = 0; in osst_ioctl()
5075 STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle", in osst_ioctl()
5076 STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number, in osst_ioctl()
5077 STp->logical_blk_num, STps->drv_file, STps->drv_block ); in osst_ioctl()
5079 if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) { in osst_ioctl()
5080 auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) && in osst_ioctl()
5086 name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos, in osst_ioctl()
5087 STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block ); in osst_ioctl()
5094 STps->rw = ST_IDLE; in osst_ioctl()
5097 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED) in osst_ioctl()
5107 if (mtc.mt_count >= STp->nbr_partitions) in osst_ioctl()
5108 retval = -EINVAL; in osst_ioctl()
5110 STp->new_partition = mtc.mt_count; in osst_ioctl()
5117 if (!STp->can_partitions) { in osst_ioctl()
5118 retval = (-EINVAL); in osst_ioctl()
5127 STp->ps[i].rw = ST_IDLE; in osst_ioctl()
5128 STp->ps[i].at_sm = 0; in osst_ioctl()
5129 STp->ps[i].last_block_valid = 0; in osst_ioctl()
5131 STp->partition = STp->new_partition = 0; in osst_ioctl()
5132 STp->nbr_partitions = 1; /* Bad guess ?-) */ in osst_ioctl()
5133 STps->drv_block = STps->drv_file = 0; in osst_ioctl()
5139 if (STp->raw) in osst_ioctl()
5143 if (!STp->can_partitions) in osst_ioctl()
5144 STp->ps[0].rw = ST_IDLE; in osst_ioctl()
5158 retval = -EINVAL; /* OnStream drives don't have compression hardware */ in osst_ioctl()
5166 if (!STm->defined) { in osst_ioctl()
5167 retval = (-ENXIO); in osst_ioctl()
5180 retval = (-EINVAL); in osst_ioctl()
5185 mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT; in osst_ioctl()
5187 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) | in osst_ioctl()
5188 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK); in osst_ioctl()
5189 mt_status.mt_blkno = STps->drv_block; in osst_ioctl()
5190 mt_status.mt_fileno = STps->drv_file; in osst_ioctl()
5191 if (STp->block_size != 0) { in osst_ioctl()
5192 if (STps->rw == ST_WRITING) in osst_ioctl()
5193 mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size; in osst_ioctl()
5194 else if (STps->rw == ST_READING) in osst_ioctl()
5195 mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes + in osst_ioctl()
5196 STp->block_size - 1) / STp->block_size; in osst_ioctl()
5200 if (STp->drv_write_prot) in osst_ioctl()
5208 mt_status.mt_resid = STp->partition; in osst_ioctl()
5209 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR) in osst_ioctl()
5211 else if (STps->eof >= ST_EOM_OK) in osst_ioctl()
5213 if (STp->density == 1) in osst_ioctl()
5215 else if (STp->density == 2) in osst_ioctl()
5217 else if (STp->density == 3) in osst_ioctl()
5219 if (STp->ready == ST_READY) in osst_ioctl()
5221 if (STp->ready == ST_NO_TAPE) in osst_ioctl()
5223 if (STps->at_sm) in osst_ioctl()
5225 if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) || in osst_ioctl()
5226 STp->drv_buffer != 0) in osst_ioctl()
5231 retval = (-EFAULT); in osst_ioctl()
5235 STp->recover_erreg = 0; /* Clear after read */ in osst_ioctl()
5244 retval = (-EINVAL); in osst_ioctl()
5247 if (STp->raw) in osst_ioctl()
5258 retval = -EFAULT; in osst_ioctl()
5263 mutex_unlock(&STp->lock); in osst_ioctl()
5265 retval = scsi_ioctl(STp->device, cmd_in, p); in osst_ioctl()
5272 mutex_unlock(&STp->lock); in osst_ioctl()
5281 struct osst_tape *STp = file->private_data; in osst_compat_ioctl()
5282 struct scsi_device *sdev = STp->device; in osst_compat_ioctl()
5283 int ret = -ENOIOCTLCMD; in osst_compat_ioctl()
5284 if (sdev->host->hostt->compat_ioctl) { in osst_compat_ioctl()
5286 ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg); in osst_compat_ioctl()
5297 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
5309 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); in new_tape_buffer()
5312 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); in new_tape_buffer()
5316 tb->sg_segs = tb->orig_sg_segs = 0; in new_tape_buffer()
5317 tb->use_sg = max_sg; in new_tape_buffer()
5318 tb->in_use = 1; in new_tape_buffer()
5319 tb->dma = need_dma; in new_tape_buffer()
5320 tb->buffer_size = 0; in new_tape_buffer()
5324 "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n", in new_tape_buffer()
5330 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
5336 if (STbuffer->buffer_size >= OS_FRAME_SIZE) in enlarge_buffer()
5339 if (STbuffer->sg_segs) { in enlarge_buffer()
5340 printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n"); in enlarge_buffer()
5343 /* See how many segments we can use -- need at least two */ in enlarge_buffer()
5344 nbr = max_segs = STbuffer->use_sg; in enlarge_buffer()
5354 for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) { in enlarge_buffer()
5357 STbuffer->sg[0].offset = 0; in enlarge_buffer()
5359 sg_set_page(&STbuffer->sg[0], page, b_size, 0); in enlarge_buffer()
5360 STbuffer->b_data = page_address(page); in enlarge_buffer()
5364 if (sg_page(&STbuffer->sg[0]) == NULL) { in enlarge_buffer()
5365 printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n"); in enlarge_buffer()
5369 for (segs=STbuffer->sg_segs=1, got=b_size; in enlarge_buffer()
5371 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order); in enlarge_buffer()
5372 STbuffer->sg[segs].offset = 0; in enlarge_buffer()
5374 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n", in enlarge_buffer()
5377 STbuffer->buffer_size = got; in enlarge_buffer()
5382 …sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - g… in enlarge_buffer()
5383 got += STbuffer->sg[segs].length; in enlarge_buffer()
5384 STbuffer->buffer_size = got; in enlarge_buffer()
5385 STbuffer->sg_segs = ++segs; in enlarge_buffer()
5390 "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n", in enlarge_buffer()
5391 got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data); in enlarge_buffer()
5394 STbuffer->sg[0].length, page_address(STbuffer->sg[0].page), in enlarge_buffer()
5395 STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page)); in enlarge_buffer()
5408 for (i=0; i < STbuffer->sg_segs; i++) { in normalize_buffer()
5411 b_size < STbuffer->sg[i].length; in normalize_buffer()
5414 __free_pages(sg_page(&STbuffer->sg[i]), order); in normalize_buffer()
5415 STbuffer->buffer_size -= STbuffer->sg[i].length; in normalize_buffer()
5418 if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs) in normalize_buffer()
5419 printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n", in normalize_buffer()
5420 STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs); in normalize_buffer()
5422 STbuffer->sg_segs = STbuffer->orig_sg_segs = 0; in normalize_buffer()
5426 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5432 for (i=0, offset=st_bp->buffer_bytes; in append_to_buffer()
5433 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) in append_to_buffer()
5434 offset -= st_bp->sg[i].length; in append_to_buffer()
5435 if (i == st_bp->sg_segs) { /* Should never happen */ in append_to_buffer()
5437 return (-EIO); in append_to_buffer()
5439 for ( ; i < st_bp->sg_segs && do_count > 0; i++) { in append_to_buffer()
5440 cnt = st_bp->sg[i].length - offset < do_count ? in append_to_buffer()
5441 st_bp->sg[i].length - offset : do_count; in append_to_buffer()
5442 res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt); in append_to_buffer()
5444 return (-EFAULT); in append_to_buffer()
5445 do_count -= cnt; in append_to_buffer()
5446 st_bp->buffer_bytes += cnt; in append_to_buffer()
5453 return (-EIO); in append_to_buffer()
5459 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5465 for (i=0, offset=st_bp->read_pointer; in from_buffer()
5466 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) in from_buffer()
5467 offset -= st_bp->sg[i].length; in from_buffer()
5468 if (i == st_bp->sg_segs) { /* Should never happen */ in from_buffer()
5470 return (-EIO); in from_buffer()
5472 for ( ; i < st_bp->sg_segs && do_count > 0; i++) { in from_buffer()
5473 cnt = st_bp->sg[i].length - offset < do_count ? in from_buffer()
5474 st_bp->sg[i].length - offset : do_count; in from_buffer()
5475 res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt); in from_buffer()
5477 return (-EFAULT); in from_buffer()
5478 do_count -= cnt; in from_buffer()
5479 st_bp->buffer_bytes -= cnt; in from_buffer()
5480 st_bp->read_pointer += cnt; in from_buffer()
5486 return (-EIO); in from_buffer()
5491 /* Sets the tail of the buffer after fill point to zero.
5497 for (i = 0, offset = st_bp->buffer_bytes; in osst_zero_buffer_tail()
5498 i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) in osst_zero_buffer_tail()
5499 offset -= st_bp->sg[i].length; in osst_zero_buffer_tail()
5500 if (i == st_bp->sg_segs) { /* Should never happen */ in osst_zero_buffer_tail()
5502 return (-EIO); in osst_zero_buffer_tail()
5504 for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes; in osst_zero_buffer_tail()
5505 i < st_bp->sg_segs && do_count > 0; i++) { in osst_zero_buffer_tail()
5506 cnt = st_bp->sg[i].length - offset < do_count ? in osst_zero_buffer_tail()
5507 st_bp->sg[i].length - offset : do_count ; in osst_zero_buffer_tail()
5508 memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt); in osst_zero_buffer_tail()
5509 do_count -= cnt; in osst_zero_buffer_tail()
5514 return (-EIO); in osst_zero_buffer_tail()
5519 /* Copy a osst 32K chunk of memory into the buffer.
5525 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) { in osst_copy_to_buffer()
5526 cnt = st_bp->sg[i].length < do_count ? in osst_copy_to_buffer()
5527 st_bp->sg[i].length : do_count ; in osst_copy_to_buffer()
5528 memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt); in osst_copy_to_buffer()
5529 do_count -= cnt; in osst_copy_to_buffer()
5532 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */ in osst_copy_to_buffer()
5535 return (-EIO); in osst_copy_to_buffer()
5540 /* Copy a osst 32K chunk of memory from the buffer.
5546 for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) { in osst_copy_from_buffer()
5547 cnt = st_bp->sg[i].length < do_count ? in osst_copy_from_buffer()
5548 st_bp->sg[i].length : do_count ; in osst_copy_from_buffer()
5549 memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt); in osst_copy_from_buffer()
5550 do_count -= cnt; in osst_copy_from_buffer()
5553 if (do_count || i != st_bp->sg_segs-1) { /* Should never happen */ in osst_copy_from_buffer()
5556 return (-EIO); in osst_copy_from_buffer()
5645 /* {"XXX", "Yy-", "", NULL}, example */ in osst_supports()
5651 /* We are willing to drive OnStream SC-x0 as well as the in osst_supports()
5653 * * emulation layer (ide-scsi, usb-storage, ...) */ in osst_supports()
5655 for (rp=&(support_list[0]); rp->vendor != NULL; rp++) in osst_supports()
5656 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) && in osst_supports()
5657 !strncmp(rp->model, SDp->model, strlen(rp->model)) && in osst_supports()
5658 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) in osst_supports()
5694 if (STp && STp->header_ok && STp->linux_media) in osst_adr_rev_show()
5695 …l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev… in osst_adr_rev_show()
5708 if (STp && STp->header_ok && STp->linux_media) in osst_linux_media_version_show()
5709 l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version); in osst_linux_media_version_show()
5721 if (STp && STp->header_ok && STp->linux_media) in osst_capacity_show()
5722 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity); in osst_capacity_show()
5735 if (STp && STp->header_ok && STp->linux_media) in osst_first_data_ppos_show()
5736 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos); in osst_first_data_ppos_show()
5749 if (STp && STp->header_ok && STp->linux_media) in osst_eod_frame_ppos_show()
5750 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos); in osst_eod_frame_ppos_show()
5762 if (STp && STp->header_ok && STp->linux_media) in osst_filemark_cnt_show()
5763 l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt); in osst_filemark_cnt_show()
5840 struct osst_buffer * buffer; in osst_probe() local
5842 int i, dev_num, err = -ENODEV; in osst_probe()
5844 if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) in osst_probe()
5845 return -ENODEV; in osst_probe()
5850 return -ENODEV; in osst_probe()
5885 /* allocate a buffer for this device */ in osst_probe()
5886 i = SDp->host->sg_tablesize; in osst_probe()
5889 buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i); in osst_probe()
5890 if (buffer == NULL) { in osst_probe()
5892 printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n"); in osst_probe()
5897 tpnt->buffer = buffer; in osst_probe()
5898 tpnt->device = SDp; in osst_probe()
5899 drive->private_data = &tpnt->driver; in osst_probe()
5900 sprintf(drive->disk_name, "osst%d", dev_num); in osst_probe()
5901 tpnt->driver = &osst_template; in osst_probe()
5902 tpnt->drive = drive; in osst_probe()
5903 tpnt->in_use = 0; in osst_probe()
5904 tpnt->capacity = 0xfffff; in osst_probe()
5905 tpnt->dirty = 0; in osst_probe()
5906 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */ in osst_probe()
5907 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma; in osst_probe()
5908 tpnt->density = 0; in osst_probe()
5909 tpnt->do_auto_lock = OSST_AUTO_LOCK; in osst_probe()
5910 tpnt->can_bsr = OSST_IN_FILE_POS; in osst_probe()
5911 tpnt->can_partitions = 0; in osst_probe()
5912 tpnt->two_fm = OSST_TWO_FM; in osst_probe()
5913 tpnt->fast_mteom = OSST_FAST_MTEOM; in osst_probe()
5914 tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */ in osst_probe()
5915 tpnt->write_threshold = osst_write_threshold; in osst_probe()
5916 tpnt->default_drvbuffer = 0xff; /* No forced buffering */ in osst_probe()
5917 tpnt->partition = 0; in osst_probe()
5918 tpnt->new_partition = 0; in osst_probe()
5919 tpnt->nbr_partitions = 0; in osst_probe()
5920 tpnt->min_block = 512; in osst_probe()
5921 tpnt->max_block = OS_DATA_SIZE; in osst_probe()
5922 tpnt->timeout = OSST_TIMEOUT; in osst_probe()
5923 tpnt->long_timeout = OSST_LONG_TIMEOUT; in osst_probe()
5927 tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev); in osst_probe()
5928 tpnt->omit_blklims = 1; in osst_probe()
5930 tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || in osst_probe()
5931 (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); in osst_probe()
5932 tpnt->frame_in_buffer = 0; in osst_probe()
5933 tpnt->header_ok = 0; in osst_probe()
5934 tpnt->linux_media = 0; in osst_probe()
5935 tpnt->header_cache = NULL; in osst_probe()
5938 STm = &(tpnt->modes[i]); in osst_probe()
5939 STm->defined = 0; in osst_probe()
5940 STm->sysv = OSST_SYSV; in osst_probe()
5941 STm->defaults_for_writes = 0; in osst_probe()
5942 STm->do_async_writes = OSST_ASYNC_WRITES; in osst_probe()
5943 STm->do_buffer_writes = OSST_BUFFER_WRITES; in osst_probe()
5944 STm->do_read_ahead = OSST_READ_AHEAD; in osst_probe()
5945 STm->default_compression = ST_DONT_TOUCH; in osst_probe()
5946 STm->default_blksize = 512; in osst_probe()
5947 STm->default_density = (-1); /* No forced density */ in osst_probe()
5951 STps = &(tpnt->ps[i]); in osst_probe()
5952 STps->rw = ST_IDLE; in osst_probe()
5953 STps->eof = ST_NOEOF; in osst_probe()
5954 STps->at_sm = 0; in osst_probe()
5955 STps->last_block_valid = 0; in osst_probe()
5956 STps->drv_block = (-1); in osst_probe()
5957 STps->drv_file = (-1); in osst_probe()
5960 tpnt->current_mode = 0; in osst_probe()
5961 tpnt->modes[0].defined = 1; in osst_probe()
5962 tpnt->modes[2].defined = 1; in osst_probe()
5963 tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; in osst_probe()
5965 mutex_init(&tpnt->lock); in osst_probe()
5977 /* No-rewind entry */ in osst_probe()
5986 SDp->model, tape_name(tpnt)); in osst_probe()
5993 kfree(buffer); in osst_probe()
6005 if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) in osst_remove()
6010 if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) { in osst_remove()
6013 tpnt->device = NULL; in osst_remove()
6014 put_disk(tpnt->drive); in osst_remove()
6016 osst_nr_dev--; in osst_remove()
6018 vfree(tpnt->header_cache); in osst_remove()
6019 if (tpnt->buffer) { in osst_remove()
6020 normalize_buffer(tpnt->buffer); in osst_remove()
6021 kfree(tpnt->buffer); in osst_remove()
6082 vfree(STp->header_cache); in exit_osst()
6083 if (STp->buffer) { in exit_osst()
6084 normalize_buffer(STp->buffer); in exit_osst()
6085 kfree(STp->buffer); in exit_osst()
6087 put_disk(STp->drive); in exit_osst()