SCCS-vsn: sys/vax/uba/uu.c 4.7
#include "uu.h"
#if NUU > 0
/*
* TU58 DECtape II/DL11 device driver
*
#include "uu.h"
#if NUU > 0
/*
* TU58 DECtape II/DL11 device driver
*
- * The TU58 * is treated as a block device (only). Error detection and
- * recovery is almost non-existant. It is assumed that the
+ * The TU58 is treated as a block device (only). Error detection and
+ * recovery is not very extensive, but sufficient to handle the most
+ * common errors. It is assumed that the
* TU58 will follow the RSP protocol exactly, very few protocol
* errors are checked for.
*/
* TU58 will follow the RSP protocol exactly, very few protocol
* errors are checked for.
*/
#include "../h/time.h"
#include "../h/kernel.h"
#include "../h/errno.h"
#include "../h/time.h"
#include "../h/kernel.h"
#include "../h/errno.h"
#include "../h/file.h"
#include "../vax/cpu.h"
#include "../h/file.h"
#include "../vax/cpu.h"
#define UNIT(dev) (minor(dev)>>1)
#define UNIT(dev) (minor(dev)>>1)
-u_char uunull[2] = { 0, 0 }; /* nulls to send for initialization */
+u_char uunull[4] = { 0, 0, 0, 0 }; /* nulls to send for initialization */
u_char uuinit[2] = { TUF_INITF, TUF_INITF }; /* inits to send */
struct uba_device *uudinfo[NUU];
u_char uuinit[2] = { TUF_INITF, TUF_INITF }; /* inits to send */
struct uba_device *uudinfo[NUU];
* is already active, just return
*/
if (uuc->tu_dopen[0] && uuc->tu_dopen[1])
* is already active, just return
*/
if (uuc->tu_dopen[0] && uuc->tu_dopen[1])
/*
* If the unit already initialized,
/*
* If the unit already initialized,
int flag;
{
register struct uu_softc *uuc;
int flag;
{
register struct uu_softc *uuc;
- int unit = UNIT(dev);
- int ctlr = unit/NDPC;
- uuc = &uu_softc[ctlr];
- if (uuc->tu_serrs + uuc->tu_cerrs + uuc->tu_herrs != 0) {
- /*
- * A tu58 is like nothing ever seen before;
- * I guess this is appropriate then...
- */
- uprintf(
- "uu%d: %d soft errors, %d checksum errors, %d hard errors\n",
- unit, uuc->tu_serrs, uuc->tu_cerrs, uuc->tu_herrs);
- uuc->tu_serrs = uuc->tu_cerrs = uuc->tu_herrs = 0;
- }
- uuc->tu_dopen[unit&UMASK] = 0;
+ uuc = &uu_softc[UNIT(dev)/NDPC];
+ uuc->tu_dopen[UNIT(dev)&UMASK] = 0;
if (ui == 0 || ui->ui_alive == 0)
goto bad;
uutab = &uitab[unit/NDPC]; /* one request queue per controller */
if (ui == 0 || ui->ui_alive == 0)
goto bad;
uutab = &uitab[unit/NDPC]; /* one request queue per controller */
if ((bp->b_flags&B_READ) == 0)
tu_pee(&pcnt[unit]);
if ((bp->b_flags&B_READ) == 0)
tu_pee(&pcnt[unit]);
bp->av_forw = NULL;
if (uutab->b_actf == NULL)
uutab->b_actf = bp;
bp->av_forw = NULL;
if (uutab->b_actf == NULL)
uutab->b_actf = bp;
* (either overrun or break)
*/
case TUS_RCVERR:
* (either overrun or break)
*/
case TUS_RCVERR:
- if (c & UURDB_ORUN)
- printf("uu(%d): data overrun, bytes left: %d",
- ui->ui_unit,
- uuc->tu_count + uuc->tu_rcnt - data->pk_mcount);
- else
- printf("uu(%d): break received", ui->ui_unit);
- printf(", transfer restarted\n");
+ if ((c & UURDB_ORUN) == 0)
+ printf("uu%d: break received, transfer restarted\n",
+ data->pk_unit);
+ uuc->tu_serrs++;
uu_restart(ctlr, ui);
break;
uu_restart(ctlr, ui);
break;
* in uudma)
*/
case TUS_GETH:
* in uudma)
*/
case TUS_GETH:
+#ifndef UUDMA
+ if (data->pk_flag == TUF_DATA)
+ uuc->tu_rbptr = (u_char *)uuc->tu_addr;
+#endif
uuc->tu_rcnt = data->pk_mcount;
uuc->tu_state = TUS_GETD;
break;
uuc->tu_rcnt = data->pk_mcount;
uuc->tu_state = TUS_GETD;
break;
if (data->pk_chksum !=
tuchk(*((short *)data), (u_short *)
(data->pk_flag == TUF_DATA ?
if (data->pk_chksum !=
tuchk(*((short *)data), (u_short *)
(data->pk_flag == TUF_DATA ?
- (u_short *) uuc->tu_addr : (u_short *)&data->pk_op),
+ (u_short *) uuc->tu_addr : (u_short *)&data->pk_op),
(int)data->pk_mcount))
case TUS_CHKERR:
uuc->tu_cerrs++;
(int)data->pk_mcount))
case TUS_CHKERR:
uuc->tu_cerrs++;
uuc->tu_flag = 0;
uuaddr->tcs = UUCS_INTR;
if ((bp = uutab->b_actf) == NULL) {
uuc->tu_flag = 0;
uuaddr->tcs = UUCS_INTR;
if ((bp = uutab->b_actf) == NULL) {
- printf("uu(%d): no bp, active %d\n",
- ui->ui_unit, uitab[ctlr].b_active);
+ printf("uu%d: no bp, active %d\n",
+ data->pk_unit, uitab[ctlr].b_active);
iodone(bp);
uustart(ui);
} else {
iodone(bp);
uustart(ui);
} else {
- printf("neither data nor end: %o %o\n",
- data->pk_flag&0xff, data->pk_op&0xff);
+ /*
+ * Neither data nor end: data was lost
+ * somehow, restart the transfer.
+ */
uuaddr->rcs = 0; /* flush the rest */
uuaddr->rcs = 0; /* flush the rest */
- uuc->tu_state = TUS_INIT1;
default:
bad:
if (c == TUF_INITF) {
default:
bad:
if (c == TUF_INITF) {
- printf("uu%d protocol error, state=", unit);
+ printf("uu%d protocol error, state=", data->pk_unit);
printstate(uuc->tu_state);
printf(", op=%x, cnt=%d, block=%d\n",
cmd->pk_op, cmd->pk_count, cmd->pk_block);
printstate(uuc->tu_state);
printf(", op=%x, cnt=%d, block=%d\n",
cmd->pk_op, cmd->pk_count, cmd->pk_block);
uuc->tu_state = TUS_INIT1;
} else {
printf("uu%d receive state error, state=",
uuc->tu_state = TUS_INIT1;
} else {
printf("uu%d receive state error, state=",
printstate(uuc->tu_state);
printf(", byte=%x\n", c & 0xff);
#ifdef notdef
printstate(uuc->tu_state);
printf(", byte=%x\n", c & 0xff);
#ifdef notdef
- case TUS_IDLE: /* stray interrupt? */
- break;
-
/*
* Read cmd packet sent, get ready for data
*/
/*
* Read cmd packet sent, get ready for data
*/
+ case TUS_IDLE: /* stray interrupt? */
+
uutab = &uitab[ctlr];
if ((uuc->tu_dopen[0] == 0) && (uuc->tu_dopen[1] == 0) &&
(uutab->b_active == 0)) {
uutab = &uitab[ctlr];
if ((uuc->tu_dopen[0] == 0) && (uuc->tu_dopen[1] == 0) &&
(uutab->b_active == 0)) {
+ /*
+ * If both devices on this controller have
+ * been closed and the request queue is
+ * empty, mark ths controller not active
+ */
uuc->tu_flag = 0;
uuaddr->rcs = 0;
continue;
uuc->tu_flag = 0;
uuaddr->rcs = 0;
continue;
uuc->tu_flag++;
if (uuc->tu_flag <= 40)
continue;
uuc->tu_flag++;
if (uuc->tu_flag <= 40)
continue;
- printf("uu(%d): read stalled\n", ctlr);
+ printf("uu%d: read stalled\n", uudata[ctlr].pk_unit);
printf("%X %X %X %X %X %X %X\n", uuc->tu_rbptr, uuc->tu_rcnt,
printf("%X %X %X %X %X %X %X\n", uuc->tu_rbptr, uuc->tu_rcnt,
- uuc->tu_wbptr, uuc->tu_wcnt, uuc->tu_state, uuc->tu_addr, uuc->tu_count);
+ uuc->tu_wbptr, uuc->tu_wcnt, uuc->tu_state, uuc->tu_addr,
+ uuc->tu_count);
uuc->tu_flag = 0;
s = splx(UUIPL);
i = uuaddr->rdb; /* dummy */
uuc->tu_flag = 0;
s = splx(UUIPL);
i = uuaddr->rdb; /* dummy */
+ * add code to wind/rewind cassette here