diff options
-rw-r--r-- | sys/scsi/st.c | 85 |
1 files changed, 79 insertions, 6 deletions
diff --git a/sys/scsi/st.c b/sys/scsi/st.c index 99bba3b8438..beaa67b7d6f 100644 --- a/sys/scsi/st.c +++ b/sys/scsi/st.c @@ -1,4 +1,4 @@ -/* $OpenBSD: st.c,v 1.71 2007/01/05 00:42:47 krw Exp $ */ +/* $OpenBSD: st.c,v 1.72 2007/01/20 18:21:51 krw Exp $ */ /* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */ /* @@ -204,6 +204,8 @@ struct st_softc { u_int64_t numblks; /* nominal blocks capacity */ u_int32_t media_blksize; /* 0 if not ST_FIXEDBLOCKS */ u_int32_t media_density; /* this is what it said when asked */ + daddr_t media_fileno; /* relative to BOT. -1 means unknown. */ + daddr_t media_blkno; /* relative to BOF. -1 means unknown. */ /*--------------------quirks for the whole drive------------------------------*/ u_int drive_quirks; /* quirks of this drive */ /*--------------------How we should set up when opening each minor device----*/ @@ -335,6 +337,10 @@ stattach(parent, self, aux) st->buf_queue.b_actf = 0; st->buf_queue.b_actb = &st->buf_queue.b_actf; + /* Start up with media position unknown. */ + st->media_fileno = -1; + st->media_blkno = -1; + /* * Reset the media loaded flag, sometimes the data * acquired at boot time is not quite accurate. This @@ -624,6 +630,9 @@ st_unmount(st, eject, rewind) struct scsi_link *sc_link = st->sc_link; int nmarks; + st->media_fileno = -1; + st->media_blkno = -1; + if (!(st->flags & ST_MOUNTED)) return; SC_DEBUG(sc_link, SDEV_DB1, ("unmounting\n")); @@ -961,6 +970,14 @@ ststart(v) } else _lto3b(bp->b_bcount, cmd.len); + if (st->media_blkno != -1) { + /* Update block count now, errors will set it to -1. */ + if (st->flags & ST_FIXEDBLOCKS) + st->media_blkno += _3btol(cmd.len); + else if (cmd.len != 0) + st->media_blkno++; + } + /* * go ask the adapter to do all this for us */ @@ -1076,8 +1093,8 @@ stioctl(dev, cmd, arg, flag, p) g->mt_dsreg |= MT_DS_MOUNTED; g->mt_resid = st->mt_resid; g->mt_erreg = st->mt_erreg; - g->mt_fileno = -1; /* -1 means we don't know */ - g->mt_blkno = -1; /* -1 means we don't know */ + g->mt_fileno = st->media_fileno; + g->mt_blkno = st->media_blkno; /* * clear latched errors. */ @@ -1592,8 +1609,35 @@ st_space(st, number, what, flags) cmd.byte2 = what; _lto3b(number, cmd.number); - return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, + error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, sizeof(cmd), 0, 0, 0, ST_SPC_TIME, NULL, flags); + + if (error != 0) { + st->media_fileno = (daddr_t) -1; + st->media_blkno = (daddr_t) -1; + } else { + switch (what) { + case SP_BLKS: + if (st->media_blkno != -1) { + st->media_blkno += number; + if (st->media_blkno < 0) + st->media_blkno = -1; + } + break; + case SP_FILEMARKS: + if (st->media_fileno != -1) { + st->media_fileno += number; + st->media_blkno = 0; + } + break; + default: + st->media_fileno = -1; + st->media_blkno = -1; + break; + } + } + + return (error); } /* @@ -1606,6 +1650,7 @@ st_write_filemarks(st, number, flags) daddr_t number; { struct scsi_write_filemarks cmd; + int error; /* * It's hard to write a negative number of file marks. @@ -1631,8 +1676,18 @@ st_write_filemarks(st, number, flags) cmd.opcode = WRITE_FILEMARKS; _lto3b(number, cmd.number); - return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, + error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, sizeof(cmd), 0, 0, 0, ST_IO_TIME * 4, NULL, flags); + + if (error != 0) { + st->media_fileno = -1; + st->media_blkno = -1; + } else if (st->media_fileno != -1) { + st->media_fileno += number; + st->media_blkno = 0; + } + + return (error); } /* @@ -1680,6 +1735,9 @@ st_load(st, type, flags) { struct scsi_load cmd; + st->media_fileno = -1; + st->media_blkno = -1; + if (type != LD_LOAD) { int error; int nmarks; @@ -1729,9 +1787,16 @@ st_rewind(st, immediate, flags) cmd.opcode = REWIND; cmd.byte2 = immediate; - return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, + error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, sizeof(cmd), 0, 0, ST_RETRIES, immediate ? ST_CTL_TIME: ST_SPC_TIME, NULL, flags); + + if (error == 0) { + st->media_fileno = 0; + st->media_blkno = 0; + } + + return (error); } /* @@ -1808,6 +1873,10 @@ st_interpret_sense(xs) } if (sense->flags & SSD_FILEMARK) { st->flags |= ST_AT_FILEMARK; + if (st->media_fileno != -1) { + st->media_fileno++; + st->media_blkno = 0; + } if (bp) bp->b_resid = xs->resid; } @@ -1848,6 +1917,10 @@ st_interpret_sense(xs) if (sense->flags & SSD_EOM) return EIO; if (sense->flags & SSD_FILEMARK) { + if (st->media_fileno != -1) { + st->media_fileno++; + st->media_blkno = 0; + } if (bp) bp->b_resid = bp->b_bcount; return 0; |