version 1.27, 1994/04/11 03:54:12 |
version 1.28, 1994/04/13 05:43:21 |
|
|
#define ST_Q_NEEDS_PAGE_0 0x00001 |
#define ST_Q_NEEDS_PAGE_0 0x00001 |
#define ST_Q_FORCE_FIXED_MODE 0x00002 |
#define ST_Q_FORCE_FIXED_MODE 0x00002 |
#define ST_Q_FORCE_VAR_MODE 0x00004 |
#define ST_Q_FORCE_VAR_MODE 0x00004 |
#define ST_Q_SNS_HLP 0x00008 /* must do READ for good MODE SENSE */ |
#define ST_Q_SENSE_HELP 0x00008 /* must do READ for good MODE SENSE */ |
#define ST_Q_IGNORE_LOADS 0x00010 |
#define ST_Q_IGNORE_LOADS 0x00010 |
#define ST_Q_BLKSIZ 0x00020 /* variable-block media_blksiz > 0 */ |
#define ST_Q_BLKSIZ 0x00020 /* variable-block media_blksiz > 0 */ |
|
|
Line 136 static struct rogues gallery[] = /* ends |
|
Line 136 static struct rogues gallery[] = /* ends |
|
{"ARCHIVE ", "VIPER 2525 25462", "????", |
{"ARCHIVE ", "VIPER 2525 25462", "????", |
0, |
0, |
{ |
{ |
{0, ST_Q_SNS_HLP, 0}, /* minor 0-3 */ |
{0, ST_Q_SENSE_HELP, 0}, /* minor 0-3 */ |
{0, ST_Q_SNS_HLP, QIC_525}, /* minor 4-7 */ |
{0, ST_Q_SENSE_HELP, QIC_525}, /* minor 4-7 */ |
{0, 0, QIC_150}, /* minor 8-11 */ |
{0, 0, QIC_150}, /* minor 8-11 */ |
{0, 0, QIC_120} /* minor 12-15 */ |
{0, 0, QIC_120} /* minor 12-15 */ |
} |
} |
Line 177 static struct rogues gallery[] = /* ends |
|
Line 177 static struct rogues gallery[] = /* ends |
|
0, |
0, |
{ |
{ |
{0, 0, 0}, /* minor 0-3 */ |
{0, 0, 0}, /* minor 0-3 */ |
{512, ST_Q_FORCE_FIXED_MODE, 0x13}, /* minor 4-7 */ |
{512, ST_Q_FORCE_FIXED_MODE, DDS}, /* minor 4-7 */ |
{1024, ST_Q_FORCE_FIXED_MODE, 0x13}, /* minor 8-11 */ |
{1024, ST_Q_FORCE_FIXED_MODE, DDS}, /* minor 8-11 */ |
{0, ST_Q_FORCE_VAR_MODE, 0x13} /* minor 12-15 */ |
{0, ST_Q_FORCE_VAR_MODE, DDS} /* minor 12-15 */ |
} |
} |
}, |
}, |
{(char *) 0} |
{0} |
}; |
}; |
|
|
#define NOEJECT 0 |
#define NOEJECT 0 |
Line 232 struct cfdriver stcd = { |
|
Line 232 struct cfdriver stcd = { |
|
}; |
}; |
|
|
int st_space __P((struct st_data *, int number, u_int what, int flags)); |
int st_space __P((struct st_data *, int number, u_int what, int flags)); |
int st_rewind __P((struct st_data *, boolean immed, int flags)); |
int st_rewind __P((struct st_data *, u_int immediate, int flags)); |
int st_mode_sense __P((struct st_data *, int flags)); |
int st_mode_sense __P((struct st_data *, int flags)); |
int st_decide_mode __P((struct st_data *, boolean first_read)); |
int st_decide_mode __P((struct st_data *, boolean first_read)); |
int st_rd_blk_lim __P((struct st_data *, int flags)); |
int st_read_block_limits __P((struct st_data *, int flags)); |
int st_touch_tape __P((struct st_data *)); |
int st_touch_tape __P((struct st_data *)); |
int st_write_filemarks __P((struct st_data *, int number, int flags)); |
int st_write_filemarks __P((struct st_data *, int number, int flags)); |
int st_load __P((struct st_data *, u_int type, int flags)); |
int st_load __P((struct st_data *, u_int type, int flags)); |
int st_mode_select __P((struct st_data *, int flags)); |
int st_mode_select __P((struct st_data *, int flags)); |
void ststrategy(); |
void ststrategy(); |
void stminphys(); |
void stminphys(); |
int st_chkeod(); |
int st_check_eod(); |
void ststart(); |
void ststart(); |
void st_unmount(); |
void st_unmount(); |
int st_mount_tape(); |
int st_mount_tape(); |
Line 625 st_mount_tape(dev, flags) |
|
Line 625 st_mount_tape(dev, flags) |
|
* Some devices can't tell you much until they have been |
* Some devices can't tell you much until they have been |
* asked to look at the media. This quirk does this. |
* asked to look at the media. This quirk does this. |
*/ |
*/ |
if (st->quirks & ST_Q_SNS_HLP) |
if (st->quirks & ST_Q_SENSE_HELP) |
if (error = st_touch_tape(st)) |
if (error = st_touch_tape(st)) |
return error; |
return error; |
/* |
/* |
* Load the physical device parameters |
* Load the physical device parameters |
* loads: blkmin, blkmax |
* loads: blkmin, blkmax |
*/ |
*/ |
if (error = st_rd_blk_lim(st, 0)) |
if (error = st_read_block_limits(st, 0)) |
return error; |
return error; |
/* |
/* |
* Load the media dependent parameters |
* Load the media dependent parameters |
Line 694 st_unmount(st, eject) |
|
Line 694 st_unmount(st, eject) |
|
if (!(st->flags & ST_MOUNTED)) |
if (!(st->flags & ST_MOUNTED)) |
return; |
return; |
SC_DEBUG(sc_link, SDEV_DB1, ("unmounting\n")); |
SC_DEBUG(sc_link, SDEV_DB1, ("unmounting\n")); |
st_chkeod(st, FALSE, &nmarks, SCSI_SILENT); |
st_check_eod(st, FALSE, &nmarks, SCSI_SILENT); |
st_rewind(st, FALSE, SCSI_SILENT); |
st_rewind(st, 0, SCSI_SILENT); |
scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT); |
scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT); |
if (eject) |
if (eject) |
st_load(st, LD_UNLOAD, SCSI_SILENT); |
st_load(st, LD_UNLOAD, SCSI_SILENT); |
|
|
continue; /* seek more work */ |
continue; /* seek more work */ |
} |
} |
} |
} |
|
|
/* |
/* |
* Fill out the scsi command |
* Fill out the scsi command |
*/ |
*/ |
bzero(&cmd, sizeof(cmd)); |
bzero(&cmd, sizeof(cmd)); |
if ((bp->b_flags & B_READ) == B_WRITE) { |
if ((bp->b_flags & B_READ) == B_WRITE) { |
cmd.op_code = WRITE_COMMAND_TAPE; |
cmd.op_code = WRITE; |
st->flags &= ~ST_FM_WRITTEN; |
st->flags &= ~ST_FM_WRITTEN; |
st->flags |= ST_WRITTEN; |
st->flags |= ST_WRITTEN; |
flags = SCSI_DATA_OUT; |
flags = SCSI_DATA_OUT; |
} else { |
} else { |
cmd.op_code = READ_COMMAND_TAPE; |
cmd.op_code = READ; |
flags = SCSI_DATA_IN; |
flags = SCSI_DATA_IN; |
} |
} |
|
|
/* |
/* |
* Handle "fixed-block-mode" tape drives by using the |
* Handle "fixed-block-mode" tape drives by using the |
* block count instead of the length. |
* block count instead of the length. |
*/ |
*/ |
if (st->flags & ST_FIXEDBLOCKS) { |
if (st->flags & ST_FIXEDBLOCKS) { |
cmd.byte2 |= SRWT_FIXED; |
cmd.byte2 |= SRW_FIXED; |
lto3b(bp->b_bcount / st->blksiz, cmd.len); |
lto3b(bp->b_bcount / st->blksiz, cmd.len); |
} else { |
} else |
lto3b(bp->b_bcount, cmd.len); |
lto3b(bp->b_bcount, cmd.len); |
} |
|
/* |
/* |
* go ask the adapter to do all this for us |
* go ask the adapter to do all this for us |
*/ |
*/ |
Line 1129 stioctl(dev, cmd, arg, flag) |
|
Line 1131 stioctl(dev, cmd, arg, flag) |
|
case MTBSF: /* backward space file */ |
case MTBSF: /* backward space file */ |
number = -number; |
number = -number; |
case MTFSF: /* forward space file */ |
case MTFSF: /* forward space file */ |
error = st_chkeod(st, FALSE, &nmarks, flags); |
error = st_check_eod(st, FALSE, &nmarks, flags); |
if (!error) |
if (!error) |
error = st_space(st, number - nmarks, |
error = st_space(st, number - nmarks, |
SP_FILEMARKS, flags); |
SP_FILEMARKS, flags); |
Line 1137 stioctl(dev, cmd, arg, flag) |
|
Line 1139 stioctl(dev, cmd, arg, flag) |
|
case MTBSR: /* backward space record */ |
case MTBSR: /* backward space record */ |
number = -number; |
number = -number; |
case MTFSR: /* forward space record */ |
case MTFSR: /* forward space record */ |
error = st_chkeod(st, TRUE, &nmarks, flags); |
error = st_check_eod(st, TRUE, &nmarks, flags); |
if (!error) |
if (!error) |
error = st_space(st, number, SP_BLKS, flags); |
error = st_space(st, number, SP_BLKS, flags); |
break; |
break; |
case MTREW: /* rewind */ |
case MTREW: /* rewind */ |
error = st_rewind(st, FALSE, flags); |
error = st_rewind(st, 0, flags); |
break; |
break; |
case MTOFFL: /* rewind and put the drive offline */ |
case MTOFFL: /* rewind and put the drive offline */ |
st_unmount(st, EJECT); |
st_unmount(st, EJECT); |
Line 1150 stioctl(dev, cmd, arg, flag) |
|
Line 1152 stioctl(dev, cmd, arg, flag) |
|
case MTNOP: /* no operation, sets status only */ |
case MTNOP: /* no operation, sets status only */ |
break; |
break; |
case MTRETEN: /* retension the tape */ |
case MTRETEN: /* retension the tape */ |
error = st_load(st, LD_RETEN, flags); |
error = st_load(st, LD_RETENSION, flags); |
if (!error) |
if (!error) |
error = st_load(st, LD_LOAD, flags); |
error = st_load(st, LD_LOAD, flags); |
break; |
break; |
case MTEOM: /* forward space to end of media */ |
case MTEOM: /* forward space to end of media */ |
error = st_chkeod(st, FALSE, &nmarks, flags); |
error = st_check_eod(st, FALSE, &nmarks, flags); |
if (!error) |
if (!error) |
error = st_space(st, 1, SP_EOM, flags); |
error = st_space(st, 1, SP_EOM, flags); |
break; |
break; |
Line 1257 st_read(st, buf, size, flags) |
|
Line 1259 st_read(st, buf, size, flags) |
|
int flags; |
int flags; |
char *buf; |
char *buf; |
{ |
{ |
struct scsi_rw_tape scsi_cmd; |
struct scsi_rw_tape cmd; |
|
|
/* |
/* |
* If it's a null transfer, return immediatly |
* If it's a null transfer, return immediatly |
*/ |
*/ |
if (size == 0) |
if (size == 0) |
return 0; |
return 0; |
bzero(&scsi_cmd, sizeof(scsi_cmd)); |
bzero(&cmd, sizeof(cmd)); |
scsi_cmd.op_code = READ_COMMAND_TAPE; |
cmd.op_code = READ; |
if (st->flags & ST_FIXEDBLOCKS) { |
if (st->flags & ST_FIXEDBLOCKS) { |
scsi_cmd.byte2 |= SRWT_FIXED; |
cmd.byte2 |= SRW_FIXED; |
lto3b(size / (st->blksiz ? st->blksiz : DEF_FIXED_BSIZE), |
lto3b(size / (st->blksiz ? st->blksiz : DEF_FIXED_BSIZE), |
scsi_cmd.len); |
cmd.len); |
} else |
} else |
lto3b(size, scsi_cmd.len); |
lto3b(size, cmd.len); |
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &scsi_cmd, |
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, |
sizeof(scsi_cmd), (u_char *) buf, size, 0, 100000, NULL, |
sizeof(cmd), (u_char *) buf, size, 0, 100000, NULL, |
flags | SCSI_DATA_IN); |
flags | SCSI_DATA_IN); |
} |
} |
|
|
Line 1287 st_read(st, buf, size, flags) |
|
Line 1289 st_read(st, buf, size, flags) |
|
* Ask the drive what it's min and max blk sizes are. |
* Ask the drive what it's min and max blk sizes are. |
*/ |
*/ |
int |
int |
st_rd_blk_lim(st, flags) |
st_read_block_limits(st, flags) |
struct st_data *st; |
struct st_data *st; |
int flags; |
int flags; |
{ |
{ |
struct scsi_blk_limits scsi_cmd; |
struct scsi_block_limits cmd; |
struct scsi_blk_limits_data scsi_blkl; |
struct scsi_block_limits_data block_limits; |
int error; |
|
struct scsi_link *sc_link = st->sc_link; |
struct scsi_link *sc_link = st->sc_link; |
|
int error; |
|
|
/* |
/* |
* First check if we have it all loaded |
* First check if we have it all loaded |
Line 1305 st_rd_blk_lim(st, flags) |
|
Line 1307 st_rd_blk_lim(st, flags) |
|
/* |
/* |
* do a 'Read Block Limits' |
* do a 'Read Block Limits' |
*/ |
*/ |
bzero(&scsi_cmd, sizeof(scsi_cmd)); |
bzero(&cmd, sizeof(cmd)); |
scsi_cmd.op_code = READ_BLK_LIMITS; |
cmd.op_code = READ_BLOCK_LIMITS; |
|
|
/* |
/* |
* do the command, update the global values |
* do the command, update the global values |
*/ |
*/ |
if (error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd, |
if (error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd, |
sizeof(scsi_cmd), (u_char *) & scsi_blkl, sizeof(scsi_blkl), |
sizeof(cmd), (u_char *) &block_limits, sizeof(block_limits), |
ST_RETRIES, 5000, NULL, flags | SCSI_DATA_IN)) |
ST_RETRIES, 5000, NULL, flags | SCSI_DATA_IN)) |
return error; |
return error; |
|
|
st->blkmin = b2tol(scsi_blkl.min_length); |
st->blkmin = b2tol(block_limits.min_length); |
st->blkmax = _3btol(&scsi_blkl.max_length_2); |
st->blkmax = _3btol(&block_limits.max_length_2); |
|
|
SC_DEBUG(sc_link, SDEV_DB3, |
SC_DEBUG(sc_link, SDEV_DB3, |
("(%d <= blksiz <= %d)\n", st->blkmin, st->blkmax)); |
("(%d <= blksiz <= %d)\n", st->blkmin, st->blkmax)); |
Line 1342 st_mode_sense(st, flags) |
|
Line 1344 st_mode_sense(st, flags) |
|
u_int scsi_sense_len; |
u_int scsi_sense_len; |
int error; |
int error; |
char *scsi_sense_ptr; |
char *scsi_sense_ptr; |
struct scsi_mode_sense scsi_cmd; |
struct scsi_mode_sense cmd; |
struct scsi_sense { |
struct scsi_sense { |
struct scsi_mode_header header; |
struct scsi_mode_header header; |
struct blk_desc blk_desc; |
struct blk_desc blk_desc; |
Line 1375 st_mode_sense(st, flags) |
|
Line 1377 st_mode_sense(st, flags) |
|
/* |
/* |
* Set up a mode sense |
* Set up a mode sense |
*/ |
*/ |
bzero(&scsi_cmd, sizeof(scsi_cmd)); |
bzero(&cmd, sizeof(cmd)); |
scsi_cmd.op_code = MODE_SENSE; |
cmd.op_code = MODE_SENSE; |
scsi_cmd.length = scsi_sense_len; |
cmd.length = scsi_sense_len; |
|
|
/* |
/* |
* do the command, but we don't need the results |
* do the command, but we don't need the results |
Line 1385 st_mode_sense(st, flags) |
|
Line 1387 st_mode_sense(st, flags) |
|
* or if we need it as a template for the mode select |
* or if we need it as a template for the mode select |
* store it away. |
* store it away. |
*/ |
*/ |
if (error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd, |
if (error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd, |
sizeof(scsi_cmd), (u_char *) scsi_sense_ptr, scsi_sense_len, |
sizeof(cmd), (u_char *) scsi_sense_ptr, scsi_sense_len, |
ST_RETRIES, 5000, NULL, flags | SCSI_DATA_IN)) |
ST_RETRIES, 5000, NULL, flags | SCSI_DATA_IN)) |
return error; |
return error; |
|
|
Line 1422 st_mode_select(st, flags) |
|
Line 1424 st_mode_select(st, flags) |
|
int flags; |
int flags; |
{ |
{ |
u_int dat_len; |
u_int dat_len; |
char *dat_ptr; |
char *dat_ptr; |
struct scsi_mode_select scsi_cmd; |
struct scsi_mode_select cmd; |
struct dat { |
struct dat { |
struct scsi_mode_header header; |
struct scsi_mode_header header; |
struct blk_desc blk_desc; |
struct blk_desc blk_desc; |
Line 1447 st_mode_select(st, flags) |
|
Line 1449 st_mode_select(st, flags) |
|
/* |
/* |
* Set up for a mode select |
* Set up for a mode select |
*/ |
*/ |
|
bzero(&cmd, sizeof(cmd)); |
|
cmd.op_code = MODE_SELECT; |
|
cmd.length = dat_len; |
|
|
bzero(dat_ptr, dat_len); |
bzero(dat_ptr, dat_len); |
bzero(&scsi_cmd, sizeof(scsi_cmd)); |
|
scsi_cmd.op_code = MODE_SELECT; |
|
scsi_cmd.length = dat_len; |
|
((struct dat *) dat_ptr)->header.blk_desc_len = sizeof(struct blk_desc); |
((struct dat *) dat_ptr)->header.blk_desc_len = sizeof(struct blk_desc); |
((struct dat *) dat_ptr)->header.dev_spec |= SMH_DSP_BUFF_MODE_ON; |
((struct dat *) dat_ptr)->header.dev_spec |= SMH_DSP_BUFF_MODE_ON; |
((struct dat *) dat_ptr)->blk_desc.density = st->density; |
((struct dat *) dat_ptr)->blk_desc.density = st->density; |
Line 1463 st_mode_select(st, flags) |
|
Line 1466 st_mode_select(st, flags) |
|
/* the Tandberg tapes need the block size to */ |
/* the Tandberg tapes need the block size to */ |
/* be set on each mode sense/select. */ |
/* be set on each mode sense/select. */ |
} |
} |
|
|
/* |
/* |
* do the command |
* do the command |
*/ |
*/ |
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &scsi_cmd, |
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, |
sizeof(scsi_cmd), (u_char *) dat_ptr, dat_len, ST_RETRIES, 5000, |
sizeof(cmd), (u_char *) dat_ptr, dat_len, ST_RETRIES, 5000, |
NULL, flags | SCSI_DATA_OUT); |
NULL, flags | SCSI_DATA_OUT); |
} |
} |
|
|
Line 1481 st_space(st, number, what, flags) |
|
Line 1485 st_space(st, number, what, flags) |
|
int flags; |
int flags; |
int number; |
int number; |
{ |
{ |
|
struct scsi_space cmd; |
int error; |
int error; |
struct scsi_space scsi_cmd; |
|
|
|
switch (what) { |
switch (what) { |
case SP_BLKS: |
case SP_BLKS: |
Line 1543 st_space(st, number, what, flags) |
|
Line 1547 st_space(st, number, what, flags) |
|
} |
} |
if (number == 0) |
if (number == 0) |
return 0; |
return 0; |
bzero(&scsi_cmd, sizeof(scsi_cmd)); |
|
scsi_cmd.op_code = SPACE; |
bzero(&cmd, sizeof(cmd)); |
scsi_cmd.byte2 = what & SS_CODE; |
cmd.op_code = SPACE; |
lto3b(number, scsi_cmd.number); |
cmd.byte2 = what; |
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &scsi_cmd, |
lto3b(number, cmd.number); |
sizeof(scsi_cmd), 0, 0, 0, 600000, NULL, flags); |
|
|
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, |
|
sizeof(cmd), 0, 0, 0, 600000, NULL, flags); |
} |
} |
|
|
/* |
/* |
Line 1560 st_write_filemarks(st, number, flags) |
|
Line 1566 st_write_filemarks(st, number, flags) |
|
int flags; |
int flags; |
int number; |
int number; |
{ |
{ |
struct scsi_write_filemarks scsi_cmd; |
struct scsi_write_filemarks cmd; |
|
|
/* |
/* |
* It's hard to write a negative number of file marks. |
* It's hard to write a negative number of file marks. |
Line 1581 st_write_filemarks(st, number, flags) |
|
Line 1587 st_write_filemarks(st, number, flags) |
|
default: |
default: |
st->flags &= ~(ST_PER_ACTION | ST_WRITTEN); |
st->flags &= ~(ST_PER_ACTION | ST_WRITTEN); |
} |
} |
bzero(&scsi_cmd, sizeof(scsi_cmd)); |
|
scsi_cmd.op_code = WRITE_FILEMARKS; |
bzero(&cmd, sizeof(cmd)); |
lto3b(number, scsi_cmd.number); |
cmd.op_code = WRITE_FILEMARKS; |
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &scsi_cmd, |
lto3b(number, cmd.number); |
sizeof(scsi_cmd), 0, 0, 0, 100000, NULL, flags); |
|
|
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, |
|
sizeof(cmd), 0, 0, 0, 100000, NULL, flags); |
} |
} |
|
|
/* |
/* |
Line 1597 st_write_filemarks(st, number, flags) |
|
Line 1605 st_write_filemarks(st, number, flags) |
|
* true, which were skipped) to get back original position. |
* true, which were skipped) to get back original position. |
*/ |
*/ |
int |
int |
st_chkeod(st, position, nmarks, flags) |
st_check_eod(st, position, nmarks, flags) |
struct st_data *st; |
struct st_data *st; |
boolean position; |
boolean position; |
int *nmarks; |
int *nmarks; |
Line 1631 st_load(st, type, flags) |
|
Line 1639 st_load(st, type, flags) |
|
u_int type; |
u_int type; |
int flags; |
int flags; |
{ |
{ |
struct scsi_load scsi_cmd; |
struct scsi_load cmd; |
struct scsi_link *sc_link = st->sc_link; |
|
|
|
bzero(&scsi_cmd, sizeof(scsi_cmd)); |
|
if (type != LD_LOAD) { |
if (type != LD_LOAD) { |
int error; |
int error; |
int nmarks; |
int nmarks; |
|
|
error = st_chkeod(st, FALSE, &nmarks, flags); |
error = st_check_eod(st, FALSE, &nmarks, flags); |
if (error) |
if (error) |
return error; |
return error; |
} |
} |
if (st->quirks & ST_Q_IGNORE_LOADS) |
if (st->quirks & ST_Q_IGNORE_LOADS) |
return 0; |
return 0; |
scsi_cmd.op_code = LOAD_UNLOAD; |
|
scsi_cmd.how |= type; |
bzero(&cmd, sizeof(cmd)); |
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &scsi_cmd, |
cmd.op_code = LOAD; |
sizeof(scsi_cmd), 0, 0, ST_RETRIES, 300000, NULL, flags); |
cmd.how = type; |
|
|
|
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, |
|
sizeof(cmd), 0, 0, ST_RETRIES, 300000, NULL, flags); |
} |
} |
|
|
/* |
/* |
* Rewind the device |
* Rewind the device |
*/ |
*/ |
int |
int |
st_rewind(st, immed, flags) |
st_rewind(st, immediate, flags) |
struct st_data *st; |
struct st_data *st; |
|
u_int immediate; |
int flags; |
int flags; |
boolean immed; |
|
{ |
{ |
struct scsi_rewind scsi_cmd; |
struct scsi_rewind cmd; |
int error; |
int error; |
int nmarks; |
int nmarks; |
|
|
error = st_chkeod(st, FALSE, &nmarks, flags); |
error = st_check_eod(st, FALSE, &nmarks, flags); |
if (error) |
if (error) |
return error; |
return error; |
st->flags &= ~ST_PER_ACTION; |
st->flags &= ~ST_PER_ACTION; |
bzero(&scsi_cmd, sizeof(scsi_cmd)); |
|
scsi_cmd.op_code = REWIND; |
bzero(&cmd, sizeof(cmd)); |
scsi_cmd.byte2 = immed ? SR_IMMED : 0; |
cmd.op_code = REWIND; |
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &scsi_cmd, |
cmd.byte2 = immediate; |
sizeof(scsi_cmd), 0, 0, ST_RETRIES, immed ? 5000 : 300000, NULL, |
|
|
return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, |
|
sizeof(cmd), 0, 0, ST_RETRIES, immediate ? 5000 : 300000, NULL, |
flags); |
flags); |
} |
} |
|
|
Line 1730 st_interpret_sense(xs) |
|
Line 1741 st_interpret_sense(xs) |
|
* drives to return proper MODE SENSE |
* drives to return proper MODE SENSE |
* information. |
* information. |
*/ |
*/ |
if ((st->quirks & ST_Q_SNS_HLP) && |
if ((st->quirks & ST_Q_SENSE_HELP) && |
!(sc_link->flags & SDEV_MEDIA_LOADED)) |
!(sc_link->flags & SDEV_MEDIA_LOADED)) |
st->blksiz -= 512; |
st->blksiz -= 512; |
} |
} |
Line 1780 st_interpret_sense(xs) |
|
Line 1791 st_interpret_sense(xs) |
|
* is required for these drives to return proper |
* is required for these drives to return proper |
* MODE SENSE information. |
* MODE SENSE information. |
*/ |
*/ |
if ((st->quirks & ST_Q_SNS_HLP) && |
if ((st->quirks & ST_Q_SENSE_HELP) && |
!(sc_link->flags & SDEV_MEDIA_LOADED)) { |
!(sc_link->flags & SDEV_MEDIA_LOADED)) { |
/* still starting */ |
/* still starting */ |
st->blksiz -= 512; |
st->blksiz -= 512; |
Line 1842 st_touch_tape(st) |
|
Line 1853 st_touch_tape(st) |
|
if (error = st_mode_select(st, 0)) |
if (error = st_mode_select(st, 0)) |
goto bad; |
goto bad; |
st_read(st, buf, readsiz, SCSI_SILENT); |
st_read(st, buf, readsiz, SCSI_SILENT); |
if (error = st_rewind(st, FALSE, 0)) { |
if (error = st_rewind(st, 0, 0)) { |
bad: free(buf, M_TEMP); |
bad: free(buf, M_TEMP); |
return error; |
return error; |
} |
} |