version 1.23, 2008/02/15 13:46:04 |
version 1.23.6.1, 2008/04/03 12:42:55 |
Line 101 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 101 __KERNEL_RCSID(0, "$NetBSD$"); |
|
|
|
#include "ioconf.h" |
#include "ioconf.h" |
|
|
struct ts { |
struct ts { |
struct cmd cmd; /* command packet */ |
struct cmd cmd; /* command packet */ |
struct chr chr; /* characteristics packet */ |
struct chr chr; /* characteristics packet */ |
struct status status; /* status packet */ |
struct status status; /* status packet */ |
}; |
}; |
|
|
/* |
/* |
|
|
* also status per tape-unit, since only one unit per controller |
* also status per tape-unit, since only one unit per controller |
* (thus we have no struct ts_info) |
* (thus we have no struct ts_info) |
*/ |
*/ |
struct ts_softc { |
struct ts_softc { |
struct device sc_dev; /* Autoconf ... */ |
device_t sc_dev; /* Autoconf ... */ |
struct uba_unit sc_unit; /* Struct common for UBA to talk */ |
struct uba_softc *sc_uh; /* the parent UBA */ |
struct evcnt sc_intrcnt; /* Interrupt counting */ |
struct uba_unit sc_unit; /* Struct common for UBA to talk */ |
struct ubinfo sc_ui; /* mapping info for struct ts */ |
struct evcnt sc_intrcnt; /* Interrupt counting */ |
struct uba_unit sc_uu; /* Struct for UBA to communicate */ |
struct ubinfo sc_ui; /* mapping info for struct ts */ |
|
struct uba_unit sc_uu; /* Struct for UBA to communicate */ |
bus_space_tag_t sc_iot; |
bus_space_tag_t sc_iot; |
bus_addr_t sc_ioh; |
bus_addr_t sc_ioh; |
bus_dma_tag_t sc_dmat; |
bus_dma_tag_t sc_dmat; |
bus_dmamap_t sc_dmam; |
bus_dmamap_t sc_dmam; |
volatile struct ts *sc_vts; /* Memory address of ts struct */ |
volatile struct ts *sc_vts; /* Memory address of ts struct */ |
struct ts *sc_bts; /* Unibus address of ts struct */ |
struct ts *sc_bts; /* Unibus address of ts struct */ |
int sc_type; /* TS11 or TS05? */ |
int sc_type; /* TS11 or TS05? */ |
short sc_waddr; /* Value to write to TSDB */ |
short sc_waddr; /* Value to write to TSDB */ |
struct bufq_state *sc_bufq; /* pending I/O requests */ |
struct bufq_state *sc_bufq; /* pending I/O requests */ |
|
|
short sc_mapped; /* Unibus map allocated ? */ |
short sc_mapped; /* Unibus map allocated ? */ |
short sc_state; /* see below: ST_xxx */ |
short sc_state; /* see below: ST_xxx */ |
short sc_rtc; /* retry count for lcmd */ |
short sc_rtc; /* retry count for lcmd */ |
short sc_openf; /* lock against multiple opens */ |
short sc_openf; /* lock against multiple opens */ |
short sc_liowf; /* last operation was write */ |
short sc_liowf; /* last operation was write */ |
struct buf ts_cbuf; /* internal cmd buffer (for ioctls) */ |
struct buf ts_cbuf; /* internal cmd buffer (for ioctls) */ |
}; |
}; |
|
|
#define XNAME sc->sc_dev.dv_xname |
#define XNAME sc->sc_dev->dv_xname |
|
|
#define TS_WCSR(csr, val) \ |
#define TS_WCSR(csr, val) \ |
bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val) |
bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val) |
Line 160 static void tsinit(struct ts_softc *); |
|
Line 161 static void tsinit(struct ts_softc *); |
|
static void tscommand(struct ts_softc *, dev_t, int, int); |
static void tscommand(struct ts_softc *, dev_t, int, int); |
static int tsstart(struct ts_softc *, int); |
static int tsstart(struct ts_softc *, int); |
static void tswchar(struct ts_softc *); |
static void tswchar(struct ts_softc *); |
static int tsreset(struct ts_softc *); |
static bool tsreset(struct ts_softc *); |
static int tsmatch(struct device *, struct cfdata *, void *); |
static int tsmatch(device_t, cfdata_t, void *); |
static void tsattach(struct device *, struct device *, void *); |
static void tsattach(device_t, device_t, void *); |
static int tsready(struct uba_unit *); |
static int tsready(struct uba_unit *); |
|
|
CFATTACH_DECL(ts, sizeof(struct ts_softc), |
CFATTACH_DECL_NEW(ts, sizeof(struct ts_softc), |
tsmatch, tsattach, NULL, NULL); |
tsmatch, tsattach, NULL, NULL); |
|
|
dev_type_open(tsopen); |
dev_type_open(tsopen); |
Line 196 const struct cdevsw ts_cdevsw = { |
|
Line 197 const struct cdevsw ts_cdevsw = { |
|
* Probe for device. If found, try to raise an interrupt. |
* Probe for device. If found, try to raise an interrupt. |
*/ |
*/ |
int |
int |
tsmatch(struct device *parent, struct cfdata *match, void *aux) |
tsmatch(device_t parent, cfdata_t match, void *aux) |
{ |
{ |
|
struct device tsdev; |
struct ts_softc ssc; |
struct ts_softc ssc; |
struct ts_softc *sc = &ssc; |
struct ts_softc *sc = &ssc; |
struct uba_attach_args *ua = aux; |
struct uba_attach_args *ua = aux; |
Line 206 tsmatch(struct device *parent, struct cf |
|
Line 208 tsmatch(struct device *parent, struct cf |
|
sc->sc_iot = ua->ua_iot; |
sc->sc_iot = ua->ua_iot; |
sc->sc_ioh = ua->ua_ioh; |
sc->sc_ioh = ua->ua_ioh; |
sc->sc_mapped = 0; |
sc->sc_mapped = 0; |
sc->sc_dev.dv_parent = parent; |
sc->sc_dev = &tsdev; |
|
sc->sc_uh = device_private(parent); |
strcpy(XNAME, "ts"); |
strcpy(XNAME, "ts"); |
|
|
/* Try to reset the device */ |
/* Try to reset the device */ |
for (i = 0; i < 3; i++) |
for (i = 0; i < 3; i++) { |
if (tsreset(sc) == 1) |
if (tsreset(sc)) |
break; |
break; |
|
} |
|
|
if (i == 3) |
if (i == 3) |
return 0; |
return 0; |
Line 222 tsmatch(struct device *parent, struct cf |
|
Line 226 tsmatch(struct device *parent, struct cf |
|
/* completion of this will raise the intr. */ |
/* completion of this will raise the intr. */ |
|
|
DELAY(1000000); /* Wait for interrupt */ |
DELAY(1000000); /* Wait for interrupt */ |
ubmemfree((void *)parent, &sc->sc_ui); |
ubmemfree(sc->sc_uh, &sc->sc_ui); |
return 1; |
return 1; |
} |
} |
|
|
/* |
/* |
*/ |
*/ |
void |
void |
tsattach(struct device *parent, struct device *self, void *aux) |
tsattach(device_t parent, device_t self, void *aux) |
{ |
{ |
struct uba_softc *uh = device_private(parent); |
|
struct ts_softc *sc = device_private(self); |
struct ts_softc *sc = device_private(self); |
struct uba_attach_args *ua = aux; |
struct uba_attach_args *ua = aux; |
int error; |
int error; |
char *t; |
const char *t; |
|
|
|
sc->sc_dev = self; |
|
sc->sc_uh = device_private(parent); |
sc->sc_iot = ua->ua_iot; |
sc->sc_iot = ua->ua_iot; |
sc->sc_ioh = ua->ua_ioh; |
sc->sc_ioh = ua->ua_ioh; |
sc->sc_dmat = ua->ua_dmat; |
sc->sc_dmat = ua->ua_dmat; |
|
|
sc->sc_uu.uu_softc = sc; |
sc->sc_uu.uu_dev = self; |
sc->sc_uu.uu_ready = tsready; |
sc->sc_uu.uu_ready = tsready; |
|
|
tsinit(sc); /* reset and map */ |
tsinit(sc); /* reset and map */ |
|
|
if ((error = bus_dmamap_create(sc->sc_dmat, (64*1024), 16, (64*1024), |
error = bus_dmamap_create(sc->sc_dmat, (64*1024), 16, (64*1024), |
0, BUS_DMA_NOWAIT, &sc->sc_dmam))) |
0, BUS_DMA_NOWAIT, &sc->sc_dmam); |
return printf(": failed create DMA map %d\n", error); |
if (error) { |
|
aprint_error(": failed create DMA map %d\n", error); |
|
return; |
|
} |
|
|
bufq_alloc(&sc->sc_bufq, "fcfs", 0); |
bufq_alloc(&sc->sc_bufq, "fcfs", 0); |
|
|
Line 257 tsattach(struct device *parent, struct d |
|
Line 265 tsattach(struct device *parent, struct d |
|
*/ |
*/ |
sc->sc_state = TS_INIT; /* tsintr() checks this ... */ |
sc->sc_state = TS_INIT; /* tsintr() checks this ... */ |
tswchar(sc); |
tswchar(sc); |
if (tsleep(sc, PRIBIO, "tsattach", 100)) |
if (tsleep(sc, PRIBIO, "tsattach", 100)) { |
return printf(": failed SET CHARACTERISTICS\n"); |
aprint_error(": failed SET CHARACTERISTICS\n"); |
|
return; |
|
} |
|
|
sc->sc_state = TS_RUNNING; |
sc->sc_state = TS_RUNNING; |
if (uh->uh_type == UBA_UBA) { |
if (sc->sc_uh->uh_type == UBA_UBA) { |
if (sc->sc_vts->status.xst2 & TS_SF_TU80) { |
if (sc->sc_vts->status.xst2 & TS_SF_TU80) { |
sc->sc_type = TYPE_TU80; |
sc->sc_type = TYPE_TU80; |
t = "TU80"; |
t = "TU80"; |
Line 274 tsattach(struct device *parent, struct d |
|
Line 284 tsattach(struct device *parent, struct d |
|
t = "TS05"; |
t = "TS05"; |
} |
} |
|
|
printf("\n%s: %s\n", XNAME, t); |
aprint_normal(": %s\n", t); |
printf("%s: rev %d, extended features %s, transport %s\n", |
aprint_normal_dev(sc->sc_dev, |
XNAME, (sc->sc_vts->status.xst2 & TS_SF_MCRL) >> 2, |
"rev %d, extended features %s, transport %s\n", |
(sc->sc_vts->status.xst2 & TS_SF_EFES ? "enabled" : "disabled"), |
(sc->sc_vts->status.xst2 & TS_SF_MCRL) >> 2, |
(TS_RCSR(TSSR) & TS_OFL ? "offline" : "online")); |
(sc->sc_vts->status.xst2 & TS_SF_EFES ? "enabled" : "disabled"), |
|
(TS_RCSR(TSSR) & TS_OFL ? "offline" : "online")); |
|
|
uba_intr_establish(ua->ua_icookie, ua->ua_cvec, tsintr, |
uba_intr_establish(ua->ua_icookie, ua->ua_cvec, tsintr, |
sc, &sc->sc_intrcnt); |
sc, &sc->sc_intrcnt); |
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt, |
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt, |
sc->sc_dev.dv_xname, "intr"); |
device_xname(sc->sc_dev), "intr"); |
} |
} |
|
|
/* |
/* |
Line 300 tsinit(struct ts_softc *sc) |
|
Line 311 tsinit(struct ts_softc *sc) |
|
* buffer into Unibus address space. |
* buffer into Unibus address space. |
*/ |
*/ |
sc->sc_ui.ui_size = sizeof(struct ts); |
sc->sc_ui.ui_size = sizeof(struct ts); |
if ((ubmemalloc((void *)device_parent(&sc->sc_dev), |
if (ubmemalloc(sc->sc_uh, &sc->sc_ui, UBA_CANTWAIT)) |
&sc->sc_ui, UBA_CANTWAIT))) |
|
return; |
return; |
sc->sc_vts = (void *)sc->sc_ui.ui_vaddr; |
sc->sc_vts = (void *)sc->sc_ui.ui_vaddr; |
sc->sc_bts = (void *)sc->sc_ui.ui_baddr; |
sc->sc_bts = (void *)sc->sc_ui.ui_baddr; |
Line 421 tsstart(struct ts_softc *sc, int isloade |
|
Line 431 tsstart(struct ts_softc *sc, int isloade |
|
cmd = TS_CMD_STAT; |
cmd = TS_CMD_STAT; |
break; |
break; |
default: |
default: |
printf ("%s: bad ioctl %d\n", sc->sc_dev.dv_xname, |
aprint_error_dev(sc->sc_dev, "bad ioctl %d\n", |
(int)bp->b_resid); |
(int)bp->b_resid); |
/* Need a no-op. get status */ |
/* Need a no-op. get status */ |
cmd = TS_CMD_STAT; |
cmd = TS_CMD_STAT; |
Line 460 tsstart(struct ts_softc *sc, int isloade |
|
Line 470 tsstart(struct ts_softc *sc, int isloade |
|
printf("tsstart: sending cmdr %x\n", sc->sc_vts->cmd.cmdr); |
printf("tsstart: sending cmdr %x\n", sc->sc_vts->cmd.cmdr); |
#endif |
#endif |
TS_WCSR(TSDB, sc->sc_waddr); |
TS_WCSR(TSDB, sc->sc_waddr); |
|
return 1; |
} |
} |
|
|
/* |
/* |
Line 468 tsstart(struct ts_softc *sc, int isloade |
|
Line 479 tsstart(struct ts_softc *sc, int isloade |
|
int |
int |
tsready(struct uba_unit *uu) |
tsready(struct uba_unit *uu) |
{ |
{ |
struct ts_softc *sc = uu->uu_softc; |
struct ts_softc *sc = device_private(uu->uu_dev); |
struct buf *bp = BUFQ_PEEK(sc->sc_bufq); |
struct buf *bp = BUFQ_PEEK(sc->sc_bufq); |
|
|
if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmam, bp->b_data, |
if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmam, bp->b_data, |
Line 508 tswchar(struct ts_softc *sc) |
|
Line 519 tswchar(struct ts_softc *sc) |
|
/* |
/* |
* Reset the TS11. Return 1 if failed, 0 if succeeded. |
* Reset the TS11. Return 1 if failed, 0 if succeeded. |
*/ |
*/ |
int |
bool |
tsreset(struct ts_softc *sc) |
tsreset(struct ts_softc *sc) |
{ |
{ |
int timeout; |
int timeout; |
Line 521 tsreset(struct ts_softc *sc) |
|
Line 532 tsreset(struct ts_softc *sc) |
|
while ((TS_RCSR(TSSR) & TS_SSR) == 0) { |
while ((TS_RCSR(TSSR) & TS_SSR) == 0) { |
DELAY(10000); |
DELAY(10000); |
if (timeout++ > 1000) |
if (timeout++ > 1000) |
return 0; |
return false; |
} |
} |
return 1; |
return true; |
} |
} |
|
|
static void |
static void |
Line 532 prtstat(struct ts_softc *sc, int sr) |
|
Line 543 prtstat(struct ts_softc *sc, int sr) |
|
char buf[100]; |
char buf[100]; |
|
|
bitmask_snprintf(sr, TS_TSSR_BITS, buf, sizeof(buf)); |
bitmask_snprintf(sr, TS_TSSR_BITS, buf, sizeof(buf)); |
printf("%s: TSSR=%s\n", XNAME, buf); |
aprint_normal_dev(sc->sc_dev, "TSSR=%s\n", buf); |
bitmask_snprintf(sc->sc_vts->status.xst0,TS_XST0_BITS,buf,sizeof(buf)); |
bitmask_snprintf(sc->sc_vts->status.xst0,TS_XST0_BITS,buf,sizeof(buf)); |
printf("%s: XST0=%s\n", XNAME, buf); |
aprint_normal_dev(sc->sc_dev, "XST0=%s\n", buf); |
} |
} |
|
|
/* |
/* |
Line 552 tsintr(void *arg) |
|
Line 563 tsintr(void *arg) |
|
|
|
short ccode = sc->sc_vts->cmd.cmdr & TS_CF_CCODE; |
short ccode = sc->sc_vts->cmd.cmdr & TS_CF_CCODE; |
|
|
|
bp = BUFQ_PEEK(sc->sc_bufq); |
#ifdef TSDEBUG |
#ifdef TSDEBUG |
{ |
{ |
char buf[100]; |
char buf[100]; |
Line 578 tsintr(void *arg) |
|
Line 590 tsintr(void *arg) |
|
* Ignore unsolicited interrupts. |
* Ignore unsolicited interrupts. |
*/ |
*/ |
log(LOG_WARNING, "%s: stray intr [%x,%x]\n", |
log(LOG_WARNING, "%s: stray intr [%x,%x]\n", |
sc->sc_dev.dv_xname, sr, mh); |
device_xname(sc->sc_dev), sr, mh); |
return; |
return; |
|
|
case TS_INIT: |
case TS_INIT: |
Line 600 tsintr(void *arg) |
|
Line 612 tsintr(void *arg) |
|
break; |
break; |
|
|
default: |
default: |
printf ("%s: unexpected interrupt during state %d [%x,%x]\n", |
aprint_error_dev(sc->sc_dev, |
sc->sc_dev.dv_xname, sc->sc_state, sr, mh); |
"unexpected interrupt during state %d [%x,%x]\n", |
|
sc->sc_state, sr, mh); |
return; |
return; |
} |
} |
|
|
Line 654 tsintr(void *arg) |
|
Line 667 tsintr(void *arg) |
|
} |
} |
#endif |
#endif |
if (sc->sc_vts->status.xst0 & TS_SF_TMK) { |
if (sc->sc_vts->status.xst0 & TS_SF_TMK) { |
|
#ifdef TSDEBUG |
|
printf(("Tape Mark detected")); |
|
#endif |
/* Read to end-of-file. No error. */ |
/* Read to end-of-file. No error. */ |
break; |
break; |
} |
} |
Line 662 tsintr(void *arg) |
|
Line 678 tsintr(void *arg) |
|
#ifdef TSDEBUG |
#ifdef TSDEBUG |
printf("TS_TC_TSA: EOT\n"); |
printf("TS_TC_TSA: EOT\n"); |
#endif |
#endif |
bp->b_error = EIO; |
if (bp != NULL) |
|
bp->b_error = EIO; |
break; |
break; |
} |
} |
if (sc->sc_vts->status.xst0 & TS_SF_RLS) |
if (sc->sc_vts->status.xst0 & TS_SF_RLS) |
break; |
break; |
if (sc->sc_vts->status.xst0 & TS_SF_TMK) { |
|
#ifdef TSDEBUG |
|
printf(("Tape Mark detected")); |
|
#endif |
|
} |
|
if (sc->sc_vts->status.xst0 & TS_SF_EOT) { |
|
#ifdef TSDEBUG |
|
printf(("End of Tape")); |
|
#endif |
|
} |
|
#ifndef TSDEBUG |
#ifndef TSDEBUG |
{ |
{ |
char buf[100]; |
char buf[100]; |
Line 729 tsintr(void *arg) |
|
Line 736 tsintr(void *arg) |
|
printf("TS_TC_TPD: errcnt %d\n", sc->sc_rtc); |
printf("TS_TC_TPD: errcnt %d\n", sc->sc_rtc); |
#endif |
#endif |
if (sc->sc_rtc++ == 8) { |
if (sc->sc_rtc++ == 8) { |
printf("%s: failed 8 retries\n", XNAME); |
aprint_error_dev(sc->sc_dev, "failed 8 retries\n"); |
prtstat(sc, sr); |
prtstat(sc, sr); |
bp->b_error = EIO; |
if (bp != NULL) |
|
bp->b_error = EIO; |
break; |
break; |
} |
} |
sc->sc_vts->cmd.cmdr = TS_CF_ACK | TS_CF_IE | TS_CMD_SRR; |
sc->sc_vts->cmd.cmdr = TS_CF_ACK | TS_CF_IE | TS_CMD_SRR; |
Line 739 tsintr(void *arg) |
|
Line 747 tsintr(void *arg) |
|
TS_WCSR(TSDB, sc->sc_waddr); |
TS_WCSR(TSDB, sc->sc_waddr); |
return; |
return; |
|
|
break; |
|
|
|
case TS_TC_TNM: |
case TS_TC_TNM: |
/* |
/* |
* Recoverable Error -- Tape position has not changed. |
* Recoverable Error -- Tape position has not changed. |
Line 748 tsintr(void *arg) |
|
Line 754 tsintr(void *arg) |
|
* reissue the original command. |
* reissue the original command. |
*/ |
*/ |
if (sc->sc_rtc++ == 8) { |
if (sc->sc_rtc++ == 8) { |
printf("%s: failed 8 retries\n", XNAME); |
aprint_error_dev(sc->sc_dev, "failed 8 retries\n"); |
prtstat(sc, sr); |
prtstat(sc, sr); |
bp->b_error = EIO; |
if (bp != NULL) |
|
bp->b_error = EIO; |
break; |
break; |
} |
} |
tsstart(sc, 1); |
tsstart(sc, 1); |
Line 762 tsintr(void *arg) |
|
Line 769 tsintr(void *arg) |
|
* No valid recovery procedures exist unless the tape |
* No valid recovery procedures exist unless the tape |
* has labels or sequence numbers. |
* has labels or sequence numbers. |
*/ |
*/ |
printf("Tape position lost\n"); |
aprint_error_dev(sc->sc_dev, "tape position lost\n"); |
bp->b_error = EIO; |
if (bp != NULL) |
|
bp->b_error = EIO; |
break; |
break; |
|
|
case TS_TC_FCE: |
case TS_TC_FCE: |
Line 774 tsintr(void *arg) |
|
Line 782 tsintr(void *arg) |
|
* fatal class code field in the TSSR register for |
* fatal class code field in the TSSR register for |
* additional information on the type of fatal error. |
* additional information on the type of fatal error. |
*/ |
*/ |
printf ("Fatal Controller Error\n"); |
aprint_error_dev(sc->sc_dev, "fatal controller error\n"); |
prtstat(sc, sr); |
prtstat(sc, sr); |
break; |
break; |
|
|
default: |
default: |
printf ("%s: error 0x%x, resetting controller\n", |
aprint_error_dev(sc->sc_dev, |
sc->sc_dev.dv_xname, sr & TS_TC); |
"error 0x%x, resetting controller\n", sr & TS_TC); |
tsreset(sc); |
tsreset(sc); |
} |
} |
if ((bp = BUFQ_GET(sc->sc_bufq)) != NULL) { |
if ((bp = BUFQ_GET(sc->sc_bufq)) != NULL) { |
Line 789 tsintr(void *arg) |
|
Line 797 tsintr(void *arg) |
|
#endif |
#endif |
if (bp != &sc->ts_cbuf) { /* no ioctl */ |
if (bp != &sc->ts_cbuf) { /* no ioctl */ |
bus_dmamap_unload(sc->sc_dmat, sc->sc_dmam); |
bus_dmamap_unload(sc->sc_dmat, sc->sc_dmam); |
uba_done((void *)device_parent(&sc->sc_dev)); |
uba_done(sc->sc_uh); |
} |
} |
bp->b_resid = sc->sc_vts->status.rbpcr; |
bp->b_resid = sc->sc_vts->status.rbpcr; |
biodone (bp); |
biodone (bp); |
Line 803 tsintr(void *arg) |
|
Line 811 tsintr(void *arg) |
|
* in the run state, call init to initialize the ts controller first. |
* in the run state, call init to initialize the ts controller first. |
*/ |
*/ |
int |
int |
tsopen(dev_t dev, int flag, int type, struct proc *p) |
tsopen(dev_t dev, int flag, int type, struct lwp *l) |
{ |
{ |
struct ts_softc *sc; |
struct ts_softc *sc = device_lookup_private(&ts_cd, TS_UNIT(dev)); |
int unit = TS_UNIT(dev); |
|
|
|
if (unit >= ts_cd.cd_ndevs) |
|
return ENXIO; |
|
|
|
sc = ts_cd.cd_devs[unit]; |
if (sc == NULL) |
if (sc == 0) |
|
return ENXIO; |
return ENXIO; |
|
|
if (sc->sc_state < TS_RUNNING) |
if (sc->sc_state < TS_RUNNING) |
Line 829 tsopen(dev_t dev, int flag, int type, st |
|
Line 832 tsopen(dev_t dev, int flag, int type, st |
|
* (ie. MTNOP) once and check the actual status.) |
* (ie. MTNOP) once and check the actual status.) |
*/ |
*/ |
if (TS_RCSR(TSSR) & TS_OFL) { |
if (TS_RCSR(TSSR) & TS_OFL) { |
uprintf("%s: transport is offline.\n", XNAME); |
uprintf("%s: transport is offline.\n", device_xname(sc->sc_dev)); |
sc->sc_openf = 0; |
sc->sc_openf = 0; |
return EIO; /* transport is offline */ |
return EIO; /* transport is offline */ |
} |
} |
tscommand(sc, dev, MTNOP, 1); |
tscommand(sc, dev, MTNOP, 1); |
if ((flag & FWRITE) && (sc->sc_vts->status.xst0 & TS_SF_WLK)) { |
if ((flag & FWRITE) && (sc->sc_vts->status.xst0 & TS_SF_WLK)) { |
uprintf("%s: no write ring.\n", XNAME); |
uprintf("%s: no write ring.\n", device_xname(sc->sc_dev)); |
sc->sc_openf = 0; |
sc->sc_openf = 0; |
return EROFS; |
return EROFS; |
} |
} |
Line 867 tsopen(dev_t dev, int flag, int type, st |
|
Line 870 tsopen(dev_t dev, int flag, int type, st |
|
* Make the tape available to others, by clearing openf flag. |
* Make the tape available to others, by clearing openf flag. |
*/ |
*/ |
int |
int |
tsclose(dev_t dev, int flag, int type, struct proc *p) |
tsclose(dev_t dev, int flag, int type, struct lwp *l) |
{ |
{ |
struct ts_softc *sc = ts_cd.cd_devs[TS_UNIT(dev)]; |
struct ts_softc *sc = device_lookup_private(&ts_cd, TS_UNIT(dev)); |
|
|
if (flag == FWRITE || ((flag & FWRITE) && sc->sc_liowf)) { |
if (flag == FWRITE || ((flag & FWRITE) && sc->sc_liowf)) { |
/* |
/* |
Line 897 tsclose(dev_t dev, int flag, int type, s |
|
Line 900 tsclose(dev_t dev, int flag, int type, s |
|
void |
void |
tsstrategy(struct buf *bp) |
tsstrategy(struct buf *bp) |
{ |
{ |
register int unit = TS_UNIT(bp->b_dev); |
struct ts_softc *sc = device_lookup_private(&ts_cd, TS_UNIT(bp->b_dev)); |
struct ts_softc *sc = (void *)ts_cd.cd_devs[unit]; |
bool empty; |
int s, empty; |
int s; |
|
|
#ifdef TSDEBUG |
#ifdef TSDEBUG |
printf("buf: %p bcount %ld blkno %d\n", bp, bp->b_bcount, bp->b_blkno); |
printf("buf: %p bcount %ld blkno %d\n", bp, bp->b_bcount, bp->b_blkno); |
Line 917 tsstrategy(struct buf *bp) |
|
Line 920 tsstrategy(struct buf *bp) |
|
* Catch ioctl commands, and call the "command" routine to do them. |
* Catch ioctl commands, and call the "command" routine to do them. |
*/ |
*/ |
int |
int |
tsioctl(dev, cmd, data, flag, p) |
tsioctl(dev_t dev, |
dev_t dev; |
u_long cmd, |
u_long cmd; |
void *data, |
void *data; |
int flag, |
int flag; |
struct lwp *l) |
struct proc *p; |
|
{ |
{ |
struct buf *bp; |
struct buf *bp; |
struct ts_softc *sc; |
struct ts_softc * const sc = device_lookup_private(&ts_cd, TS_UNIT(dev)); |
struct mtop *mtop; /* mag tape cmd op to perform */ |
struct mtop *mtop; /* mag tape cmd op to perform */ |
struct mtget *mtget; /* mag tape struct to get info in */ |
struct mtget *mtget; /* mag tape struct to get info in */ |
int callcount; /* number of times to call routine */ |
int callcount; /* number of times to call routine */ |
Line 937 tsioctl(dev, cmd, data, flag, p) |
|
Line 939 tsioctl(dev, cmd, data, flag, p) |
|
printf("tsioctl (%x, %lx, %p, %d)\n", dev, cmd, data, flag); |
printf("tsioctl (%x, %lx, %p, %d)\n", dev, cmd, data, flag); |
#endif |
#endif |
|
|
sc = ts_cd.cd_devs[TS_UNIT(dev)]; |
|
bp = &sc->ts_cbuf; |
bp = &sc->ts_cbuf; |
|
|
switch (cmd) { |
switch (cmd) { |
Line 1058 tswrite(dev_t dev, struct uio *uio, int |
|
Line 1059 tswrite(dev_t dev, struct uio *uio, int |
|
* |
* |
*/ |
*/ |
int |
int |
tsdump(dev, blkno, va, size) |
tsdump(dev_t dev, daddr_t blkno, void *va, size_t size) |
dev_t dev; |
|
daddr_t blkno; |
|
void *va; |
|
size_t size; |
|
{ |
{ |
return EIO; |
return EIO; |
} |
} |