int position_blocks_forw(uint32_t count, uint8_t *sam_stat) { uint32_t residual; uint32_t blk_target; unsigned int i; if (!tape_loaded(sam_stat)) { return -1; } if (mam.MediumType == MEDIA_TYPE_WORM) OK_to_write = 0; blk_target = raw_pos.hdr.blk_number + count; /* Find the first filemark forward from our current position, if any. */ for (i = 0; i < meta.filemark_count; i++) { MHVTL_DBG(3, "filemark at %ld", (unsigned long)filemarks[i]); if (filemarks[i] >= raw_pos.hdr.blk_number) { break; } } /* If there is one, see if it is between our current position and our desired destination. */ if (i < meta.filemark_count) { if (filemarks[i] >= blk_target) { return position_to_block(blk_target, sam_stat); } residual = blk_target - raw_pos.hdr.blk_number + 1; if (read_header(filemarks[i] + 1, sam_stat)) { return -1; } MHVTL_DBG(1, "Filemark encountered: block %d", filemarks[i]); mkSenseBuf(NO_SENSE | SD_FILEMARK, E_MARK, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } if (blk_target > eod_blk_number) { residual = blk_target - eod_blk_number; if (read_header(eod_blk_number, sam_stat)) { return -1; } MHVTL_DBG(1, "EOD encountered"); mkSenseBuf(BLANK_CHECK, E_END_OF_DATA, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } return position_to_block(blk_target, sam_stat); }
int position_filemarks_back(uint32_t count, uint8_t *sam_stat) { uint32_t residual; int i; if (!tape_loaded(sam_stat)) return -1; if (mam.MediumType == MEDIA_TYPE_WORM) OK_to_write = 0; /* Find the block number of the first filemark less than our current position. */ for (i = meta.filemark_count - 1; i >= 0; i--) if (filemarks[i] < raw_pos.hdr.blk_number) break; if (i + 1 >= count) return position_to_block(filemarks[i - count + 1], sam_stat); else { residual = count - i - 1; if (read_header(0, sam_stat)) return -1; sam_no_sense(SD_EOM, E_BOM, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } }
int position_filemarks_forw(uint32_t count, uint8_t *sam_stat) { uint32_t residual; unsigned int i; if (!tape_loaded(sam_stat)) return -1; if (mam.MediumType == MEDIA_TYPE_WORM) OK_to_write = 0; /* Find the block number of the first filemark greater than our current position. */ for (i = 0; i < meta.filemark_count; i++) if (filemarks[i] >= raw_pos.hdr.blk_number) break; if (i + count - 1 < meta.filemark_count) return position_to_block(filemarks[i + count - 1] + 1, sam_stat); else { residual = i + count - meta.filemark_count; if (read_header(eod_blk_number, sam_stat)) return -1; sam_blank_check(E_END_OF_DATA, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } }
uint8_t ssc_seek_10(struct scsi_cmd *cmd) { uint32_t blk_no; current_state = MHVTL_STATE_LOCATE; MHVTL_DBG(1, "Fast Block Locate (%ld) **", (long)cmd->dbuf_p->serialNo); blk_no = get_unaligned_be32(&cmd->scb[3]); /* If we want to seek closer to beginning of file than * we currently are, rewind and seek from there */ MHVTL_DBG(2, "Current blk: %d, seek: %d", c_pos->blk_number, blk_no); position_to_block(blk_no, &cmd->dbuf_p->sam_stat); return cmd->dbuf_p->sam_stat; }
int position_blocks_back(uint32_t count, uint8_t *sam_stat) { uint32_t residual; uint32_t blk_target; int i = -1; unsigned int num_filemarks = meta.filemark_count; if (!tape_loaded(sam_stat)) return -1; if (mam.MediumType == MEDIA_TYPE_WORM) OK_to_write = 0; MHVTL_DBG(2, "Position before movement: %d", raw_pos.hdr.blk_number); if (count < raw_pos.hdr.blk_number) blk_target = raw_pos.hdr.blk_number - count; else blk_target = 0; /* Find the first filemark prior to our current position, if any. */ if (num_filemarks > 0) { for (i = num_filemarks - 1; i >= 0; i--) { MHVTL_DBG(3, "filemark at %ld", (unsigned long)filemarks[i]); if (filemarks[i] < raw_pos.hdr.blk_number) break; } } /* If there is one, see if it is between our current position and our desired destination. */ if (i >= 0) { if (filemarks[i] < blk_target) return position_to_block(blk_target, sam_stat); residual = raw_pos.hdr.blk_number - blk_target; if (read_header(filemarks[i], sam_stat)) return -1; MHVTL_DBG(2, "Filemark encountered: block %d", filemarks[i]); sam_no_sense(SD_FILEMARK, E_MARK, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } if (count > raw_pos.hdr.blk_number) { residual = count - raw_pos.hdr.blk_number; if (read_header(0, sam_stat)) return -1; MHVTL_DBG(1, "BOM encountered"); sam_no_sense(SD_EOM, E_BOM, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } return position_to_block(blk_target, sam_stat); }