1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)uu.c 7.2 (Berkeley) 04/25/89 7 */ 8 9 #include "uu.h" 10 #if NUU > 0 11 /* 12 * TU58 DECtape II/DL11 device driver 13 * 14 * The TU58 is treated as a block device (only). Error detection and 15 * recovery is not very extensive, but sufficient to handle the most 16 * common errors. It is assumed that the TU58 will follow the RSP 17 * protocol exactly, very few protocol errors are checked for. 18 * 19 * To reduce interrupt latency, `options UUDMA' should be specified 20 * in the config file to make sure the `pseudo-DMA' code in locore.s 21 * will be compiled into the system. Otherwise overrun errors will 22 * occur frequently (these errors are not reported). 23 * 24 * TODO: 25 * 26 * - Add ioctl code to wind/rewind cassette 27 * 28 */ 29 30 #include "machine/pte.h" 31 32 #include "param.h" 33 #include "systm.h" 34 #include "buf.h" 35 #include "conf.h" 36 #include "time.h" 37 #include "kernel.h" 38 #include "errno.h" 39 #include "file.h" 40 41 #include "../vax/cpu.h" 42 #include "../vax/nexus.h" 43 #include "../vax/rsp.h" 44 45 #include "ubavar.h" 46 #include "ubareg.h" 47 #include "uureg.h" 48 49 #define NTUBLK 512 /* number of blocks on a TU58 cassette */ 50 #define WRV 01 /* bit in minor dev => write w. read verify */ 51 #define NDPC 02 /* drives per controller */ 52 #define NUX NDPC * NUU /* number of drives */ 53 #define NUUQ 02 /* # of block which can be queued up */ 54 #define UMASK 01 /* unit number mask */ 55 #define UUIPL 0x14 /* ipl level to use */ 56 57 struct packet uucmd[NUU]; /* a command sent to the TU58 */ 58 struct packet uudata[NUU]; /* a command or data returned from TU58 */ 59 struct buf uitab[NUU]; /* buffer queue headers */ 60 61 /* 62 * Driver soft carrier structure 63 */ 64 struct uu_softc { 65 u_char *tu_rbptr; /* pointer to buffer for read */ 66 int tu_rcnt; /* how much to read */ 67 u_char *tu_wbptr; /* pointer to buffer for write */ 68 int tu_wcnt; /* how much to write */ 69 int tu_state; /* current state of tansfer operation */ 70 int tu_flag; /* read in progress flag */ 71 char *tu_addr; /* real buffer data address */ 72 int tu_count; /* real requested count */ 73 int tu_serrs; /* count of soft errors */ 74 int tu_cerrs; /* count of checksum errors */ 75 int tu_herrs; /* count of hard errors */ 76 char tu_dopen[2]; /* drive is open */ 77 } uu_softc[NUU]; 78 79 #if defined(VAX750) || defined(VAX730) 80 extern char *tustates[]; 81 #else 82 char *tustates[TUS_NSTATES] = { 83 "INIT1", "INIT2", "IDLE", "SENDH", "SENDD", "SENDC", "SENDR", 84 "SENDW", "GETH", "GETD", "GETC", "GET", "WAIT", "RCVERR", "CHKERR" 85 }; 86 #endif 87 88 #define UNIT(dev) (minor(dev)>>1) 89 90 u_char uunull[2] = { 0, 0 }; /* nulls to send for initialization */ 91 u_char uuinit[2] = { TUF_INITF, TUF_INITF }; /* inits to send */ 92 93 struct uba_device *uudinfo[NUU]; 94 95 int uuprobe(), uuattach(), uurintr(), uuxintr(), uuwatch(); 96 u_short uustd[] = { 0176500, 0 }; 97 struct uba_driver uudriver = 98 { uuprobe, 0, uuattach, 0, uustd, "uu", uudinfo }; 99 100 int uuwstart; 101 int uuwake(); 102 static char uu_pcnt[NUX]; /* pee/vee counters, one per drive */ 103 104 /*ARGSUSED*/ 105 uuprobe(reg) 106 caddr_t reg; 107 { 108 register int br, cvec; /* value result */ 109 struct uudevice *uuaddr = (struct uudevice *)reg; 110 111 #ifdef lint 112 br = 0; cvec = br; br = cvec; 113 uurintr(0); uuxintr(0); 114 #endif 115 uuaddr->tcs = UUCS_INTR; 116 DELAY(1000); 117 uuaddr->tcs = 0; 118 cvec -= 4; /* since we are using the xmitter intrpt */ 119 return(sizeof (*uuaddr)); 120 } 121 122 uuattach(ui) 123 register struct uba_device *ui; 124 { 125 } 126 127 /*ARGSUSED1*/ 128 uuopen(dev, flag) 129 dev_t dev; 130 int flag; 131 { 132 register struct uba_device *ui; 133 register struct uu_softc *uuc; 134 register struct uudevice *uuaddr; 135 int ctlr, unit = UNIT(dev), s; 136 137 ctlr = unit / NDPC; 138 if (unit >= NUX || (ui = uudinfo[ctlr]) == 0 || ui->ui_alive == 0) 139 return (ENXIO); 140 uuc = &uu_softc[ctlr]; 141 if (uuc->tu_dopen[unit&UMASK]) 142 return (EBUSY); 143 if (uuwstart++ == 0) 144 timeout(uuwatch, (caddr_t)0, hz); 145 146 uuc->tu_dopen[unit&UMASK]++; 147 uuaddr = (struct uudevice *)ui->ui_addr; 148 s = splx(UUIPL); 149 /* 150 * If the other device on this controller 151 * is already active, no need to initialize 152 */ 153 if (uuc->tu_dopen[0] && uuc->tu_dopen[1]) 154 goto ok; 155 156 /* 157 * If the unit already initialized, 158 * just enable interrupts and return. 159 */ 160 if (uuc->tu_state == TUS_IDLE) { 161 uuaddr->rcs = UUCS_INTR; 162 goto ok; 163 } 164 165 /* 166 * Must initialize, reset the cassette 167 * and wait for things to settle down. 168 */ 169 uureset(ctlr); 170 sleep((caddr_t)uuc, PZERO+1); 171 uitab[ctlr].b_active = NULL; 172 if (uuc->tu_state != TUS_IDLE) { 173 uuc->tu_state = TUS_INIT1; 174 uuc->tu_dopen[unit&UMASK] = 0; 175 uuc->tu_rcnt = uuc->tu_wcnt = 0; 176 uuaddr->rcs = 0; 177 uuaddr->tcs = 0; 178 splx(s); 179 return (EIO); 180 } 181 ok: 182 splx(s); 183 return (0); 184 } 185 186 /* 187 * Wait for all outstanding IO on this drive 188 * complete, before closing. If both drives on 189 * this controller are idle, mark the controller 190 * `inactive'. 191 */ 192 193 uuclose(dev, flag) 194 dev_t dev; 195 int flag; 196 { 197 int s, unit = UNIT(dev); 198 register struct uu_softc *uuc = &uu_softc[unit/NDPC]; 199 struct buf *bp, *last = NULL; 200 struct uudevice *uuaddr = (struct uudevice *)uudinfo[unit/NDPC]->ui_addr; 201 202 s = splx(UUIPL); 203 while (uu_pcnt[unit]) 204 sleep(&uu_pcnt[unit], PRIBIO); 205 /* 206 * No more writes are pending, scan the 207 * buffer queue for oustanding reads from 208 * this unit. 209 */ 210 for (bp = uitab[unit/NDPC].b_actf; bp; bp = bp->b_actf) { 211 if (bp->b_dev == dev) 212 last = bp; 213 } 214 if (last) { 215 last->b_flags |= B_CALL; 216 last->b_iodone = uuwake; 217 sleep((caddr_t)last, PRIBIO); 218 } 219 uuc->tu_dopen[unit&UMASK] = 0; 220 if (!uuc->tu_dopen[0] && !uuc->tu_dopen[1]) { 221 uuc->tu_flag = 0; 222 uuaddr->rcs = 0; 223 } 224 splx(s); 225 } 226 227 uuwake(bp) 228 struct buf *bp; 229 { 230 wakeup(bp); 231 } 232 233 uureset(ctlr) 234 int ctlr; 235 { 236 register struct uu_softc *uuc = &uu_softc[ctlr]; 237 register struct packet *cmd = &uucmd[ctlr]; 238 struct uba_device *ui = uudinfo[ctlr]; 239 register struct uudevice *uuaddr = (struct uudevice *)ui->ui_addr; 240 241 uitab[ctlr].b_active++; 242 uuc->tu_state = TUS_INIT1; 243 uuc->tu_wbptr = uunull; 244 uuc->tu_wcnt = sizeof (uunull); 245 uuc->tu_rcnt = 0; 246 cmd->pk_flag = TUF_CMD; 247 cmd->pk_mcount = sizeof (*cmd) - 4; 248 cmd->pk_mod = 0; 249 cmd->pk_seq = 0; 250 cmd->pk_sw = 0; 251 uuaddr->rcs = 0; 252 uuaddr->tcs = UUCS_INTR | UUCS_BREAK; 253 uuxintr(ctlr); /* start output */ 254 } 255 256 /* 257 * Strategy routine for block I/O 258 */ 259 uustrategy(bp) 260 register struct buf *bp; 261 { 262 register struct buf *uutab; 263 struct uba_device *ui; 264 int s, unit = UNIT(bp->b_dev); 265 266 if ((unit > NUX) || (bp->b_blkno >= NTUBLK)) 267 goto bad; 268 ui = uudinfo[unit/NDPC]; 269 if (ui == 0 || ui->ui_alive == 0) 270 goto bad; 271 uutab = &uitab[unit/NDPC]; /* one request queue per controller */ 272 s = splx(UUIPL); 273 if ((bp->b_flags&B_READ) == 0) 274 tu_pee(&uu_pcnt[unit]); 275 bp->b_actf = NULL; 276 if (uutab->b_actf == NULL) 277 uutab->b_actf = bp; 278 else 279 uutab->b_actl->b_actf = bp; 280 uutab->b_actl = bp; 281 if (uutab->b_active == 0) 282 uustart(ui); 283 splx(s); 284 return; 285 286 bad: 287 bp->b_flags |= B_ERROR; 288 bp->b_error = ENXIO; 289 iodone(bp); 290 return; 291 } 292 293 /* 294 * Start the transfer 295 */ 296 uustart(ui) 297 register struct uba_device *ui; 298 { 299 register struct buf *bp; 300 register struct uu_softc *uuc; 301 struct packet *cmd; 302 int ctlr = ui->ui_unit, s; 303 304 if ((bp = uitab[ctlr].b_actf) == NULL) 305 return; 306 s = splx(UUIPL); 307 uuc = &uu_softc[ctlr]; 308 if (uuc->tu_state != TUS_IDLE) { 309 uureset(ctlr); 310 splx(s); 311 return; 312 } 313 cmd = &uucmd[ctlr]; 314 uitab[ctlr].b_active++; 315 uitab[ctlr].b_errcnt = 0; 316 uuc->tu_addr = bp->b_un.b_addr; 317 uuc->tu_count = cmd->pk_count = bp->b_bcount; 318 cmd->pk_block = bp->b_blkno; 319 if (bp->b_flags&B_READ) { 320 cmd->pk_op = TUOP_READ; 321 cmd->pk_mod = 0; 322 uuc->tu_state = TUS_SENDR; 323 } else { 324 cmd->pk_op = TUOP_WRITE; 325 cmd->pk_mod = minor(bp->b_dev)&WRV ? TUMD_WRV : 0; 326 uuc->tu_state = TUS_SENDW; 327 } 328 cmd->pk_unit = UNIT(bp->b_dev)&UMASK; 329 cmd->pk_sw = 0; 330 cmd->pk_chksum = 331 tuchk(*((short *)cmd), (u_short *)&cmd->pk_op, (int)cmd->pk_mcount); 332 uuc->tu_wbptr = (u_char *)cmd; 333 uuc->tu_wcnt = sizeof (*cmd); 334 uuxintr(ctlr); 335 splx(s); 336 } 337 338 /* 339 * TU58 receiver interrupt, handles whatever condition the 340 * pseudo DMA routine in locore is unable to handle, 341 * or, if UUDMA is undefined, handle all receiver interrupt 342 * processing. 343 */ 344 uurintr(ctlr) 345 int ctlr; 346 { 347 struct uba_device *ui = uudinfo[ctlr]; 348 register struct uu_softc *uuc = &uu_softc[ctlr]; 349 register struct uudevice *uuaddr = (struct uudevice *)ui->ui_addr; 350 register struct buf *uutab = &uitab[ctlr]; 351 struct packet *data, *cmd; 352 struct buf *bp; 353 int c, unit; 354 355 c = uuaddr->rdb; 356 data = &uudata[ctlr]; 357 cmd = &uucmd[ctlr]; 358 #if !defined(UUDMA) 359 if (c & UURDB_ERROR) 360 uuc->tu_state = TUS_RCVERR; 361 else { 362 if (uuc->tu_rcnt) { 363 *uuc->tu_rbptr++ = c; 364 if (--uuc->tu_rcnt) 365 return; 366 } 367 } 368 #endif 369 370 /* 371 * Switch on the tu_state of the transfer. 372 */ 373 switch(uuc->tu_state) { 374 375 /* 376 * A data error occured in uudma 377 * (either overrun or break) 378 */ 379 case TUS_RCVERR: 380 if ((c & UURDB_ORUN) == 0) 381 printf("uu%d: break received, transfer restarted\n", 382 data->pk_unit); 383 #ifdef UUDEBUG 384 else 385 printf("uu%d: data overrun, recovered\n", 386 data->pk_unit); 387 #endif 388 uuc->tu_serrs++; 389 uu_restart(ctlr, ui); 390 break; 391 392 /* 393 * If we get an unexpected "continue", 394 * start all over again... 395 */ 396 case TUS_INIT2: 397 uuc->tu_state = c == TUF_CONT ? TUS_IDLE : TUS_INIT1; 398 uuc->tu_flag = 0; 399 wakeup((caddr_t)uuc); 400 uustart(ui); 401 break; 402 403 /* 404 * Only transition from this state 405 * is on a "continue", so if we don't 406 * get it, reset the world. 407 */ 408 case TUS_WAIT: /* waiting for continue */ 409 switch(c) { 410 case TUF_CONT: /* got the expected continue */ 411 uuc->tu_flag = 0; 412 data->pk_flag = TUF_DATA; 413 data->pk_mcount = MIN(128, uuc->tu_count); 414 data->pk_chksum = 415 tuchk(*((short *)data), (caddr_t)uuc->tu_addr, 416 (int)data->pk_mcount); 417 uuc->tu_state = TUS_SENDH; 418 uuc->tu_wbptr = (u_char *)data; 419 uuc->tu_wcnt = 2; 420 uuxintr(ctlr); 421 break; 422 423 case TUF_CMD: /* sending us an END packet...error */ 424 uuc->tu_state = TUS_GET; 425 uuc->tu_rbptr = (u_char *)data; 426 uuc->tu_rcnt = sizeof (*data) - 1; 427 uuc->tu_flag = 1; 428 uuaddr->tcs = 0; 429 *uuc->tu_rbptr++ = c & UUDB_DMASK; 430 break; 431 432 case TUF_INITF: 433 uureset(ctlr); 434 break; 435 436 default: /* something random...bad news */ 437 uuc->tu_state = TUS_INIT1; 438 break; 439 } 440 break; 441 442 case TUS_SENDW: 443 if (c != TUF_CONT && c != TUF_INITF) 444 goto bad; 445 uu_restart(ctlr, ui); 446 break; 447 448 /* 449 * Got header, now get data; amount to 450 * fetch is included in packet. 451 * (data packets are handled entirely 452 * in uudma) 453 */ 454 case TUS_GETH: 455 #ifndef UUDMA 456 if (data->pk_flag == TUF_DATA) 457 uuc->tu_rbptr = (u_char *)uuc->tu_addr; 458 #endif 459 uuc->tu_rcnt = data->pk_mcount; 460 uuc->tu_state = TUS_GETD; 461 break; 462 463 /* 464 * Got the data, now fetch the checksum. 465 */ 466 case TUS_GETD: 467 uuc->tu_rbptr = (u_char *)&data->pk_chksum; 468 uuc->tu_rcnt = sizeof (data->pk_chksum); 469 uuc->tu_state = TUS_GETC; 470 break; 471 472 case TUS_GETC: 473 /* got entire packet */ 474 if (data->pk_chksum != 475 tuchk(*((short *)data), (u_short *) 476 (data->pk_flag == TUF_DATA ? 477 (u_short *) uuc->tu_addr : (u_short *)&data->pk_op), 478 (int)data->pk_mcount)) 479 case TUS_CHKERR: 480 uuc->tu_cerrs++; 481 case TUS_GET: 482 if (data->pk_flag == TUF_DATA) { 483 /* data packet, advance to next */ 484 uuc->tu_addr += data->pk_mcount; 485 uuc->tu_count -= data->pk_mcount; 486 uuc->tu_state = TUS_GETH; 487 uuc->tu_rbptr = (u_char *)data; /* next packet */ 488 uuc->tu_rcnt = 2; 489 } else if (data->pk_flag==TUF_CMD && data->pk_op==TUOP_END) { 490 /* end packet, idle and reenable transmitter */ 491 uuc->tu_state = TUS_IDLE; 492 uuc->tu_flag = 0; 493 uuaddr->tcs = UUCS_INTR; 494 if ((bp = uutab->b_actf) == NULL) { 495 printf("uu%d: no bp, active %d\n", 496 data->pk_unit, uitab[ctlr].b_active); 497 uustart(ui); 498 return; 499 } 500 unit = UNIT(bp->b_dev); 501 if (data->pk_mod > 1) { /* hard error */ 502 printf("uu%d: hard error bn%d,", unit, 503 bp->b_blkno); 504 printf(" pk_mod 0%o\n", data->pk_mod&0xff); 505 bp->b_flags |= B_ERROR; 506 uuc->tu_herrs++; 507 } else if (data->pk_mod) /* soft error */ 508 uuc->tu_serrs++; 509 uutab->b_active = NULL; 510 uutab->b_actf = bp->b_actf; 511 bp->b_resid = uuc->tu_count; 512 if ((bp->b_flags&B_READ) == 0) 513 tu_vee(&uu_pcnt[unit]); 514 iodone(bp); 515 uustart(ui); 516 } else { 517 /* 518 * Neither data nor end: data was lost 519 * somehow, flush and restart the transfer. 520 */ 521 uuaddr->rcs = 0; 522 uu_restart(ctlr, ui); 523 uuc->tu_serrs++; 524 } 525 break; 526 527 case TUS_IDLE: 528 case TUS_INIT1: 529 break; 530 531 default: 532 bad: 533 if (c == TUF_INITF) { 534 printf("uu%d protocol error, state=", data->pk_unit); 535 printstate(uuc->tu_state); 536 printf(", op=%x, cnt=%d, block=%d\n", 537 cmd->pk_op, cmd->pk_count, cmd->pk_block); 538 uutab->b_active = NULL; 539 if (bp = uutab->b_actf) { 540 bp->b_flags |= B_ERROR; 541 uutab->b_actf = bp->b_actf; 542 if ((bp->b_flags&B_READ) == 0) 543 tu_vee(&uu_pcnt[unit]); 544 iodone(bp); 545 } 546 uuc->tu_state = TUS_INIT1; 547 } else { 548 printf("uu%d receive state error, state=", 549 data->pk_unit); 550 printstate(uuc->tu_state); 551 printf(", byte=%x\n", c & 0xff); 552 #ifdef notdef 553 uuc->tu_state = TUS_INIT1; 554 #endif 555 wakeup((caddr_t)uuc); 556 } 557 } 558 } 559 560 561 /* 562 * TU58 transmitter interrupt 563 */ 564 uuxintr(ctlr) 565 int ctlr; 566 { 567 register struct uu_softc *uuc = &uu_softc[ctlr]; 568 register struct uudevice *uuaddr; 569 register struct packet *data; 570 struct uba_device *ui = uudinfo[ctlr]; 571 int c; 572 573 data = &uudata[ctlr]; 574 uuaddr = (struct uudevice *) ui->ui_addr; 575 top: 576 if (uuc->tu_wcnt > 0) { 577 /* still stuff to send, send one byte */ 578 while ((uuaddr->tcs & UUCS_READY) == 0) 579 ; 580 uuaddr->tdb = *uuc->tu_wbptr++; 581 uuc->tu_wcnt--; 582 return; 583 } 584 585 /* 586 * Last message byte was sent out. 587 * Switch on tu_state of transfer. 588 */ 589 switch(uuc->tu_state) { 590 591 /* 592 * Two nulls have been sent, remove break, and send inits 593 */ 594 case TUS_INIT1: 595 uuc->tu_flag = 0; 596 uuaddr->tcs = UUCS_INTR; 597 uuc->tu_state = TUS_INIT2; 598 uuc->tu_wbptr = uuinit; 599 uuc->tu_wcnt = sizeof (uuinit); 600 goto top; 601 602 /* 603 * Inits have been sent, wait for a continue msg. 604 */ 605 case TUS_INIT2: 606 c = uuaddr->rdb; /* prevent overrun error */ 607 uuaddr->rcs = UUCS_INTR; 608 uuc->tu_flag = 1; 609 break; 610 611 /* 612 * Read cmd packet sent, get ready for data 613 */ 614 case TUS_SENDR: 615 uuc->tu_state = TUS_GETH; 616 uuc->tu_rbptr = (u_char *)data; 617 uuc->tu_rcnt = 2; 618 uuc->tu_flag = 1; 619 uuaddr->tcs = 0; 620 uuaddr->rcs = UUCS_INTR; 621 break; 622 623 /* 624 * Write cmd packet sent, wait for continue 625 */ 626 case TUS_SENDW: 627 uuc->tu_state = TUS_WAIT; 628 uuc->tu_flag = 1; 629 if ((uuaddr->rcs&UUCS_INTR) == 0) { 630 printf("NO IE\n"); 631 uuaddr->rcs = UUCS_INTR; 632 } 633 break; 634 635 /* 636 * Header sent, send data. 637 */ 638 case TUS_SENDH: 639 uuc->tu_state = TUS_SENDD; 640 uuc->tu_wbptr = (u_char *)uuc->tu_addr; 641 uuc->tu_wcnt = data->pk_mcount; 642 goto top; 643 644 /* 645 * Data sent, follow with checksum. 646 */ 647 case TUS_SENDD: 648 uuc->tu_state = TUS_SENDC; 649 uuc->tu_wbptr = (u_char *)&data->pk_chksum; 650 uuc->tu_wcnt = 2; 651 goto top; 652 653 /* 654 * Checksum sent, wait for continue. 655 */ 656 case TUS_SENDC: 657 /* 658 * Update buffer address and count. 659 */ 660 uuc->tu_addr += data->pk_mcount; 661 uuc->tu_count -= data->pk_mcount; 662 if (uuc->tu_count > 0) { 663 uuc->tu_state = TUS_WAIT; 664 uuc->tu_flag = 1; 665 break; 666 } 667 668 /* 669 * End of transmission, get ready for end packet. 670 */ 671 uuc->tu_state = TUS_GET; 672 uuc->tu_rbptr = (u_char *)data; 673 uuc->tu_rcnt = sizeof (*data); 674 uuc->tu_flag = 1; 675 uuaddr->tcs = 0; 676 break; 677 678 /* 679 * Random interrupt 680 */ 681 case TUS_IDLE: /* stray interrupt? */ 682 683 default: 684 break; 685 } 686 } 687 688 uuwatch() 689 { 690 register struct uu_softc *uuc; 691 register struct uudevice *uuaddr; 692 struct uba_device *ui; 693 struct buf *bp, *uutab; 694 int s, ctlr, active = 0; 695 696 for (ctlr=0; ctlr<NUU; ctlr++) { 697 int i; 698 699 uuc = &uu_softc[ctlr]; 700 701 if (uuc->tu_dopen[0] || uuc->tu_dopen[1]) 702 active++; 703 if (uuc->tu_flag == 0) 704 /* 705 * If no read is in progress 706 * just skip 707 */ 708 continue; 709 710 ui = uudinfo[ctlr]; 711 uuaddr = (struct uudevice *)ui->ui_addr; 712 uutab = &uitab[ctlr]; 713 if (uuc->tu_flag++ < 40) 714 continue; 715 printf("uu%d: read stalled\n", uudata[ctlr].pk_unit); 716 #ifdef UUDEBUG 717 printf("%X %X %X %X %X %X %X\n", uuc->tu_rbptr, uuc->tu_rcnt, 718 uuc->tu_wbptr, uuc->tu_wcnt, uuc->tu_state, uuc->tu_addr, 719 uuc->tu_count); 720 #endif 721 s = splx(UUIPL); 722 uuc->tu_flag = 0; 723 i = uuaddr->rdb; /* dummy */ 724 uuaddr->rcs = UUCS_INTR; /* in case we were flushing */ 725 uuaddr->tcs = UUCS_INTR; 726 uuc->tu_state = TUS_IDLE; 727 if (!uutab->b_active) { 728 wakeup((caddr_t)uuc); 729 goto retry; 730 } 731 if (++uutab->b_errcnt <= 1) { 732 uustart(ui); 733 goto retry; 734 } 735 if (bp = uutab->b_actf) { 736 bp->b_flags |= B_ERROR; 737 if ((bp->b_flags&B_READ) == 0) 738 tu_vee(&uu_pcnt[UNIT(bp->b_dev)]); 739 iodone(bp); 740 } 741 retry: 742 (void) splx(s); 743 } 744 if (active) 745 timeout(uuwatch, (caddr_t)0, hz); 746 else 747 uuwstart = 0; 748 return; 749 } 750 751 #if !defined(VAX750) && !defined(VAX730) 752 /* 753 * Compute checksum TU58 fashion 754 */ 755 #ifdef lint 756 tuchk(word, cp, n) 757 register word; 758 register unsigned short *cp; 759 int n; 760 { 761 register int c = n >> 1; 762 register long temp; 763 764 do { 765 temp = *cp++; /* temp, only because vax cc won't *r++ */ 766 word += temp; 767 } while (--c > 0); 768 if (n & 1) 769 word += *(unsigned char *)cp; 770 while (word & 0xffff0000) 771 word = (word & 0xffff) + ((word >> 16) & 0xffff); 772 return (word); 773 } 774 #else 775 tuchk(word0, wp, n) 776 register int word0; /* r11 */ 777 register char *wp; /* r10 */ 778 register int n; /* r9 */ 779 { 780 asm("loop:"); 781 asm(" addw2 (r10)+,r11"); /* add a word to sum */ 782 asm(" adwc $0,r11"); /* add in carry, end-around */ 783 asm(" acbl $2,$-2,r9,loop"); /* done yet? */ 784 asm(" blbc r9,ok"); /* odd byte count? */ 785 asm(" movzbw (r10),r10"); /* yes, get last byte */ 786 asm(" addw2 r10,r11"); /* add it in */ 787 asm(" adwc $0,r11"); /* and the carry */ 788 asm("ok:"); 789 asm(" movl r11,r0"); /* return sum */ 790 } 791 #endif 792 793 /* 794 * Make sure this incredibly slow device 795 * doesn't eat up all the buffers in the 796 * system by putting the requesting process 797 * (remember: this device is 'single-user') 798 * to sleep if the write-behind queue grows 799 * larger than NUUQ. 800 */ 801 tu_pee(cp) 802 char *cp; 803 { 804 register int s; 805 806 s = splx(UUIPL); 807 if (++(*cp) > NUUQ) 808 sleep(cp, PRIBIO); 809 splx(s); 810 } 811 812 tu_vee(cp) 813 char *cp; 814 { 815 register int s; 816 817 s = splx(UUIPL); 818 if (--(*cp) <= NUUQ) 819 wakeup(cp); 820 splx(s); 821 } 822 #endif 823 824 uuioctl(dev, cmd, data, flag) 825 dev_t dev; 826 caddr_t data; 827 { 828 /* 829 * add code to wind/rewind cassette here 830 */ 831 return (ENXIO); 832 } 833 834 uu_restart(ctlr, ui) 835 int ctlr; 836 struct uba_device *ui; 837 { 838 uureset(ctlr); 839 timeout(uustart, (caddr_t)ui, hz * 3); 840 } 841 842 #endif 843