1 /* 2 * Datakit driver 3 * DR11C version without KMC 4 * 5 * uses mbufs for transmission 6 * 7 * SCCSID[] = "@(#)dkit_dr.c 1.5 Garage 84/04/11" 8 */ 9 10 #include "dkitdr.h" 11 #if NDKITDR>0 12 #include "datakit.h" 13 14 #include "../machine/pte.h" 15 #include "param.h" 16 #include "time.h" 17 #include "kernel.h" 18 #include "buf.h" 19 #include "mbuf.h" 20 #include "errno.h" 21 #include "socket.h" 22 #include "syslog.h" 23 #include "../net/if.h" 24 #include "../vaxuba/ubareg.h" 25 #include "../vaxuba/ubavar.h" 26 27 #include "dk.h" 28 #include "dkit.h" 29 #include "dkdr.h" 30 31 32 #define PKBHOG 64 /* max temp buffers per channel */ 33 #define DKNPKB (200+4*NDATAKIT) 34 #define DKNSTB 10 35 36 struct dkchan dkit[NDATAKIT]; 37 extern int dk_nchan; 38 39 int dkdr_npk = DKNPKB; 40 struct dkpkbufr dk_pkbuf[DKNPKB]; 41 42 int dkdr_nstat = DKNSTB; 43 struct dkstat dkdr_stat[DKNSTB]; 44 45 int dkattached = 0; /* Is it really there? */ 46 47 #ifdef KALYPSO 48 #define URPDEBUG 5000 49 #else 50 #define URPDEBUG 500 51 #endif 52 53 #ifdef URPDEBUG 54 int dkurpdebug = 0; 55 #define URPTRACE(chan, chr, Dkp) if (dkurpdebug == (chan)) \ 56 dkurptrace(chr, Dkp); 57 #endif 58 59 /* 60 * structure of data in first mbuf on chain (type DKM_HDR) 61 * 62 */ 63 struct mpacket { 64 short mp_len; /* Total length left */ 65 char mp_ctl; /* Control character */ 66 int mp_eob; /* Send end-of-block indicator */ 67 int (*mp_endfcn)(); /* End-action function */ 68 caddr_t mp_endparm; /* Parameter to above function */ 69 }; 70 71 /* 72 * dr11-c bit definitions 73 */ 74 #define DKTENAB 0100 /* transmit interrupt enable */ 75 #define DKRENAB 040 /* receiver interrupt enable */ 76 #define ENABS 0140 /* both enables */ 77 #define DKCOM 03 /* dr11-c command bits */ 78 #define DKTDONE 0200 /* transmit done bit */ 79 #define DKRDONE 0100000 /* receiver done bit */ 80 #define DKMARK 01000 /* start of packet bit */ 81 #define DKOVF 040000 /* receiver overflow bit (in drin) */ 82 #define DKDATA 0400 /* bit 9 ... indicates non-control */ 83 84 #define DKCHUNK 16 /* packet size */ 85 86 /* 87 * dr11c commands 88 */ 89 #define D_OSEQ 0 90 #define D_READ 1 91 #define D_WRITE 2 92 #define D_XPACK 3 93 94 /* 95 * error control protocol definitions 96 */ 97 #define SEQ 0010 /* 8 sequence numbers to end trailers */ 98 #define ECHO 0020 /* 8 echoes, data given to host */ 99 #define REJ 0030 /* 8 rejections, transmission error */ 100 #define ACK 0040 /* first of 8 acks, correct reception */ 101 #define BOT 0050 /* normal beginning of trailer */ 102 #define BOTM 0051 /* trailer with more data to follow */ 103 #define BOTS 0052 /* seq update algorithm on this trailer */ 104 #define SOI 0053 /* start of interrupt trailer */ 105 #define EOI 0054 /* end of interrupt trailer */ 106 #define ENQ 0055 /* xmitter request flow/error status */ 107 #define CHECK 0056 /* xmitter request error status */ 108 #define INITREQ 0057 /* request initialization */ 109 #define INIT0 0060 /* disable trailer processing */ 110 #define INIT1 0061 /* enable trailer processing */ 111 #define AINIT 0062 /* response to INIT0/INIT1 */ 112 113 #define DKBMASK 03 /* this xmitter has window size of 4, */ 114 /* #define DKBLOCK 60 /* each message is 60 bytes */ 115 #define DKBLOCK 28 /* each message is 60 bytes */ 116 117 118 /* 119 * some commonly used macros 120 */ 121 122 123 124 struct dkpkbufr *dk_Sfree; 125 extern int dkdr_npk; 126 extern struct dkpkbufr dk_pkbuf[]; 127 128 int dknopkb = 1 ; /* Counter for 'no dkpkbufr' condition. */ 129 int dkstray; /* number of stray interrupts since last timeout */ 130 int dkdrlostint; /* Number of lost receiver interrupts */ 131 int dkdisabled; /* flag to indicate that DK interface has been disabled 132 due to stray interrupts, etc. */ 133 #define MAX_STRAY 10 /* maximum number of stray interrupts 134 before temporarily disabling DK interrupts */ 135 136 /* 137 * dr11c device registers 138 */ 139 struct rdevice { 140 short dkcsr; 141 short dko; 142 short dki; 143 }; 144 145 extern int dkdr_nstat; 146 extern struct dkstat dkdr_stat[]; 147 148 static char Hstat, Tstat; 149 150 #define DKADDR ((struct rdevice *) dkitdrdinfo[0]->ui_addr) 151 152 153 /* 154 * Intermediate level command codes 155 */ 156 #define KS_SEND 20 157 #define KS_RDB 21 158 #define KS_EOI 22 159 #define KS_CNTL 23 160 #define KS_ERR 24 161 162 163 164 int dkdebug = 512 ; 165 int dkactive ; 166 167 static int timeron; 168 169 170 int dkitdrprobe(), dkitdrattach(); 171 struct uba_device *dkitdrdinfo[1]; 172 u_short dkitdrstd[] = { 0 }; 173 struct uba_driver dkitdrdriver = 174 { dkitdrprobe, 0, dkitdrattach, 0, dkitdrstd, "dkitdr", dkitdrdinfo }; 175 176 dkitdrprobe(reg) 177 caddr_t reg; 178 { 179 register int br, cvec; /* value-result */ 180 register struct rdevice *draddr = (struct rdevice *) reg; 181 register int i, c; 182 183 #ifdef lint 184 br = 0; cvec = br; br = cvec; 185 dkdrrint(0); dkdrxint(0); 186 #endif 187 draddr->dkcsr = D_READ; 188 for (i = 0; i < 1024; i++) 189 if (draddr->dkcsr & DKRDONE) c = draddr->dki; 190 else break; 191 #ifdef lint 192 c = c; 193 #endif 194 draddr->dkcsr = D_WRITE; 195 draddr->dko = DKMARK | (dk_nchan-1); /* pack on 511 */ 196 draddr->dkcsr = D_XPACK + DKTENAB; 197 draddr->dko = 0; 198 DELAY(10000); 199 draddr->dkcsr = 0; 200 return(sizeof(struct rdevice)); 201 } 202 203 /*ARGSUSED*/ 204 dkitdrattach(ui) 205 struct uba_device *ui; 206 { 207 dkattached = 1; 208 209 #if defined(INET) && NDKI>0 210 dkiattach(); 211 #endif 212 } 213 214 215 static 216 dk_init() 217 { 218 register struct rdevice *raddr = DKADDR; 219 register s ; 220 /* 221 * At attach time for the hardware device 222 * initialize and check things out to the 223 * (grumble) limited extent that is possible. 224 */ 225 226 s = spl5() ; 227 Hstat = Tstat = 0 ; 228 dkdisabled = 0; 229 dkstray = 0; 230 { 231 register struct dkchan *dkp ; 232 233 for (dkp = &dkit[0]; dkp < &dkit[dk_nchan]; dkp++) { 234 dkp->dk_rlen = 0 ; 235 dkp->dk_xlen = 0 ; 236 dkp->dk_X = XM_OFF; 237 dkp->dk_rq = NULL ; 238 dkp->dk_outq.ifq_len = 0; 239 dkp->dk_outq.ifq_maxlen = 20; 240 dkp->dk_outq.ifq_drops = 0; 241 dkp->dk_outq.ifq_head = NULL; 242 dkp->dk_outq.ifq_tail = NULL; 243 } 244 } { register struct dkpkbufr *pkb ; 245 246 for (pkb = &dk_pkbuf[1]; pkb < &dk_pkbuf[dkdr_npk-1]; pkb++) { 247 pkb->Pnext = pkb + 1 ; 248 } 249 dk_pkbuf[dkdr_npk-1].Pnext = NULL ; 250 dk_Sfree = &dk_pkbuf[1] ; 251 dk_pkbuf[0].Pnext = NULL ; 252 } { 253 register int seq, i, c ; 254 255 raddr->dkcsr = D_OSEQ ; 256 raddr->dko = 0 ; /* clears all FIFO's */ 257 seq = 0 ; 258 while (raddr->dkcsr & DKTDONE) { 259 seq += (((raddr->dki)>>10) & 017) + 2 ; 260 if (seq > 100) { 261 dkreport(KS_ERR, 0, 1, 0, 1) ; 262 splx(s) ; 263 return -EIO ; 264 } 265 } 266 raddr->dkcsr = D_READ; 267 for (i = 0; i < 1024; i++) 268 if (raddr->dkcsr & DKRDONE) c = raddr->dki; 269 else break; 270 #ifdef lint 271 c = c; 272 #endif 273 } 274 raddr->dkcsr = ENABS ; 275 if(!timeron){ 276 dk_timeout(); 277 timeron++; 278 } 279 280 splx(s) ; 281 dkactive = 1 ; 282 283 284 return 0 ; 285 } 286 287 /*ARGSUSED*/ 288 dkitreset(uban) 289 int uban; 290 { 291 register struct rdevice *raddr ; 292 293 raddr = DKADDR; 294 raddr->dkcsr = ENABS; 295 log(LOG_ERR, " dkit_dr%d", 0); 296 } 297 298 dk_open(chan, supfcn) 299 register chan ; 300 int (*supfcn)() ; 301 { 302 register struct dkchan *dkp; 303 register s ; 304 extern dkkint() ; 305 static firsttime = 1; 306 static init; 307 extern int commchan; 308 309 if (chan >= dk_nchan || !dkattached) 310 return -ENXIO ; 311 if (firsttime) { 312 if ((init = dk_init()) < 0) return init; 313 firsttime = 0; 314 } 315 dkp = &dkit[chan] ; 316 s = spl5() ; 317 /* 318 * Channel 0 (0-3 in ISN) is reserved for maintenance. 319 * An open on channel 0 is interpreted as a request 320 * for an unused channel. Channel 1 (4 in ISN or RADIAN) 321 * is the common supervisory channel. 322 */ 323 if (chan == 0) { 324 chan = commchan+1 ; /* Start above commchan */ 325 while (1) { 326 dkp = &dkit[chan] ; 327 if (dkp->dk_state == 0) 328 break ; 329 chan++ ; 330 if (chan >= dk_nchan) { 331 splx(s) ; 332 return -EADDRNOTAVAIL ; 333 } 334 } 335 } 336 337 338 /* 339 * Finish setting up dkp struct. 340 */ 341 if ((dkp->dk_state & DK_OPEN) ==0) { 342 if (chan > dkdebug) 343 log(LOG_ERR, "dkopen %d: %x\n", chan, supfcn) ; 344 dkp->dk_S = 1 ; 345 dkp->dk_R = 0 ; 346 dkp->dk_X = 0 ; 347 dkp->dk_A = 0 ; 348 dkp->dk_rejcnt = 0; 349 dkp->dk_srejcnt = 0; 350 dkp->dk_ackrejcnt = 0; 351 dkp->dk_enqcnt = 0; 352 dksend(chan, INIT1) ; 353 flushall(dkp, 0); 354 dkp->dk_state &= ~DK_LINGR ; 355 dkp->dk_state |= DK_OPEN; 356 } 357 dkp->dk_supfcn = supfcn ; 358 splx(s) ; 359 return chan ; 360 } 361 362 363 /* 364 * Close a channel: 365 */ 366 367 dk_close(chan) 368 { 369 register struct dkchan *dkp; 370 register s ; 371 372 s = spl5() ; 373 if (chan > dkdebug) 374 log(LOG_ERR, "dkclose %d\n", chan) ; 375 dkp = &dkit[chan] ; 376 if (chan == 0) { 377 if (!dkattached) return -ENXIO; 378 for (dkp = &dkit[1]; dkp < &dkit[dk_nchan]; dkp++) { 379 if (dkp->dk_state & (DK_OPEN|DK_BUSY|DK_RCV)) { 380 dkp->dk_state |= DK_RESET ; 381 flushall(dkp, 0) ; 382 } 383 } 384 dkactive = 0 ; 385 splx(s); 386 return dk_init() ; 387 } else { 388 dkp->dk_state |= DK_OPEN ; 389 flushall(dkp, 0) ; 390 dkp->dk_state = DK_LINGR ; 391 dkp->dk_X = XM_OFF; 392 dkp->dk_trmode = 0 ; 393 } 394 splx(s) ; 395 return 0; 396 } 397 398 /* 399 * Close phase 2 - mark available for reassignment 400 */ 401 dk_free(chan) 402 { 403 if (chan > dkdebug) 404 log(LOG_ERR, "dkfree %d\n", chan) ; 405 dkit[chan].dk_state &= ~DK_LINGR ; 406 } 407 408 409 /* 410 * Reset a channel 411 * prevents further I/O until close 412 */ 413 dk_reset(chan) 414 { 415 register struct dkchan *dkp ; 416 register s ; 417 418 if (chan > dkdebug) 419 log(LOG_ERR, "dkreset %d\n", chan) ; 420 s = spl5() ; 421 dkp = &dkit[chan] ; 422 dkp->dk_state |= DK_RESET ; 423 flushall(dkp, 0) ; 424 splx(s) ; 425 } 426 427 428 429 /* 430 * Xmit a short control (interrupt) packet 431 */ 432 dk_xint(chan, intr) 433 { 434 register struct rdevice *raddr ; 435 register s ; 436 register struct dkchan *dkp ; 437 438 dkp = &dkit[chan] ; 439 if (chan == 0 || dkp->dk_X < XM_INIT) 440 return -1 ; 441 s = spl5() ; 442 if (chan > dkdebug) 443 log(LOG_ERR, "dkxint %d: %o %o\n", chan, (intr & 0377), ((intr >>8)&0377)) ; 444 raddr = DKADDR ; 445 raddr->dkcsr = D_WRITE ; 446 raddr->dko = chan | DKMARK ; 447 raddr->dko = SOI ; 448 raddr->dko = (intr & 0377) | DKDATA ; 449 raddr->dko = ((intr >> 8) & 0377) | DKDATA ; 450 raddr->dko = EOI ; 451 raddr->dkcsr = D_XPACK ; 452 raddr->dko = 0 ; 453 if(dkdisabled) 454 raddr->dko = 0; 455 else 456 raddr->dko = ENABS; 457 splx(s) ; 458 return 0 ; 459 } 460 461 462 /* 463 * Adjust window size 464 */ 465 dk_winsize(chan, win) 466 struct diocxwin win; 467 { 468 return EINVAL; /* For now... */ 469 } 470 471 472 /* 473 * Xmit data on a channel 474 * NOTE * * * * * 475 * Although it is never checked here, buffer addresses 476 * in this version of the driver must be kernel addressable. 477 */ 478 dk_xmit(chan, m, eob, ctlchar, endfcn, endparm) 479 struct mbuf *m ; 480 int (*endfcn)() ; 481 caddr_t endparm ; 482 { 483 register struct dkchan *dkp ; 484 register struct mpacket *mbp ; 485 register struct mbuf *mb; 486 int s ; 487 488 s = spl5() ; 489 dkp = &dkit[chan] ; 490 if ((dkp->dk_state & DK_RESET) || (mb = m_get(M_DONTWAIT,DKMT_HDR)) == NULL) { 491 m_freem(m); 492 splx(s) ; 493 return 0 ; 494 } 495 496 if (ctlchar == '\001') eob = 0; 497 mb->m_len = 0; 498 mbp = mtod(mb, struct mpacket *); 499 mbp->mp_endfcn = endfcn ; 500 mbp->mp_endparm = endparm ; 501 mbp->mp_eob = eob; 502 mb->m_next = m; 503 504 mbp->mp_len = 0; 505 while (m) { 506 #ifdef notdef 507 if (m->m_type != DKMT_DATA && m->m_type != DKMT_CTL) { 508 log(LOG_ERR, "dk_xmit %d: got type %x\n", chan, m->m_type); 509 m_freem(mb); 510 return 0; 511 } 512 #endif 513 mbp->mp_len += m->m_len; 514 m = m->m_next; 515 } 516 517 if ((ctlchar & 0300) == 0100) { 518 register struct mbuf *n = mb, *mc; 519 520 mc = m_get(M_DONTWAIT, DKMT_CTL); 521 if (mc == NULL) { 522 m_freem(mb); 523 splx(s); 524 return 0; 525 } 526 *mtod(mc, char *) = ctlchar; 527 mc->m_len = 1; 528 529 /* Append it -- can't use m_cat because type field counts */ 530 while (n->m_next) n = n->m_next; 531 n->m_next = mc; 532 mbp->mp_len++; 533 ctlchar = 0; 534 } 535 mbp->mp_ctl = ctlchar; 536 537 if ((dkp->dk_state & DK_BUSY) == 0) { 538 dkp->dk_state |= DK_BUSY ; 539 dkp->dk_curout = mb; 540 dkp->dk_xlen = mbp->mp_len ; 541 if (chan > dkdebug) 542 log(LOG_ERR, "xmit %d: %x len %d\n", chan, 543 mb->m_next, mbp->mp_len) ; 544 dkxmit(dkp, chan, 2) ; 545 splx(s) ; 546 return dkp->dk_state ; 547 } 548 if (IF_QFULL(&dkp->dk_outq)) { 549 IF_DROP(&dkp->dk_outq); 550 m_freem(mb); 551 } 552 else 553 IF_ENQUEUE(&dkp->dk_outq, mb); 554 splx(s) ; 555 return dkp->dk_state ; 556 } 557 558 /* 559 * Receive into a block buffer 560 */ 561 dk_recv(chan, addr, len, mode, endfcn, endparm) 562 caddr_t addr ; 563 int (*endfcn)() ; 564 caddr_t endparm ; 565 { 566 register struct dkchan *dkp ; 567 register s ; 568 569 if (addr == 0) { 570 log(LOG_ERR, "dk_recv: channel %d endfcn %x: invalid address specification\n", chan, endfcn); 571 return 0; 572 } 573 574 s = spl5() ; 575 dkp = &dkit[chan] ; 576 if (dkp->dk_state & (DK_RCV | DK_RESET)) { 577 splx(s) ; 578 return 0 ; 579 } 580 dkp->dk_state |= DK_RCV ; 581 dkp->dk_endfcn = endfcn ; 582 dkp->dk_endparm = endparm ; 583 dkp->dk_rmode = mode ; 584 dkp->dk_rlen = len ; 585 dkp->dk_raddr = (caddr_t)addr ; 586 if (chan > dkdebug) 587 log(LOG_ERR, "dkrecv %d: %x len %d mode %o\n", chan, (caddr_t)addr, len, mode) ; 588 dkrcv(dkp, chan, 2) ; 589 splx(s) ; 590 return dkp->dk_state ; 591 } 592 593 594 dk_rabort(chan, nendfcn, nendparm) 595 int (*nendfcn)() ; 596 caddr_t nendparm ; 597 { 598 register struct dkchan *dkp ; 599 register s ; 600 601 dkp = &dkit[chan] ; 602 s = spl5() ; 603 if (dkp->dk_state & DK_RCV) { 604 dkp->dk_state &= ~DK_RCV ; 605 if (dkp->dk_rlen) { 606 if (chan > dkdebug) 607 log(LOG_ERR, "rcvabo %d: rlen %d\n", chan, dkp->dk_rlen) ; 608 (*nendfcn)(nendparm, chan, dkp->dk_rlen, DKR_ABORT, 0) ; 609 } 610 dkp->dk_rlen = 0 ; 611 } 612 splx(s) ; 613 return dkp->dk_state ; 614 } 615 616 617 618 dk_status(chan) 619 { 620 if (chan >= dk_nchan) 621 return 0 ; 622 return dkit[chan].dk_state ; 623 } 624 625 626 dk_timeout() 627 { 628 register struct rdevice *raddr; 629 register struct dkchan *dkp; 630 register chan ; 631 int s = spl5(); 632 633 chan = 0 ; 634 for (dkp = &dkit[0]; dkp < &dkit[dk_nchan]; dkp++) { 635 if (dkp->dk_X != XM_OFF) { 636 if (dkp->dk_X == 0) 637 dksend(chan, INIT1) ; 638 else 639 if (dkp->dk_S != ((dkp->dk_R + 1) & 07)) { 640 if (dkp->dk_X & XM_ENQ) { 641 dksend(chan, ENQ) ; 642 dkp->dk_X &= ~XM_REJ ; 643 dkp->dk_enqcnt++; 644 URPTRACE(chan, ENQ, dkp); 645 } 646 else dkp->dk_X |= XM_ENQ; 647 } 648 } 649 chan++ ; 650 } 651 652 dkstray = 0; 653 if(dkdisabled){ 654 if(dkdisabled++ > 10){ 655 /* try re-enabling interrupts */ 656 dkdisabled = 0; 657 log(LOG_ERR, "re-enabling DK interface\n"); 658 raddr = DKADDR; 659 raddr->dkcsr = ENABS; 660 } 661 } 662 else { 663 /* Look for lost interrupts */ 664 if (raddr->dkcsr < 0) { 665 dkdrlostint++; 666 dkdrxint(0); 667 } 668 } 669 670 timeout(dk_timeout, (caddr_t) 0, 1*hz); 671 splx(s); 672 } 673 674 dk_cmd(chan, cmd) 675 { 676 register struct dkchan *dkp ; 677 int s = spl5(); 678 679 if (chan > dkdebug) 680 log(LOG_ERR, "dkcmd %d: %o\n", chan, cmd) ; 681 dkp = &dkit[chan] ; 682 if (cmd & DKC_XINIT) { 683 dkp->dk_X = dkp->dk_R = dkp->dk_A = 0 ; 684 dkp->dk_S = 1 ; 685 dksend(chan, INIT1) ; 686 } 687 if (cmd & DKC_FLUSH) { 688 flushall(dkp, -1) ; 689 } 690 if (cmd & DKC_SPND) 691 dkp->dk_state |= DK_SPND ; 692 if (cmd & DKC_RSME) { 693 dkp->dk_state &= ~DK_SPND ; 694 dkxmit(dkp, chan, 2) ; 695 } 696 splx(s); 697 } 698 699 700 static 701 flushall(dkp, rwflag) 702 register struct dkchan *dkp ; 703 { 704 register s ; 705 struct mpacket *mbp; 706 707 s = spl5() ; 708 if ((dkp->dk_state & DK_RCV) && (rwflag >= 0)) { 709 dkp->dk_state &= ~DK_RCV ; 710 if (dkp->dk_endfcn) 711 (*dkp->dk_endfcn)(dkp->dk_endparm, dkp-dkit, dkp->dk_rlen, DKR_ABORT, 0) ; 712 dkp->dk_rlen = 0 ; 713 } 714 if ((dkp->dk_state & DK_BUSY) && (rwflag <= 0)) { 715 register struct mbuf *m ; 716 717 dkp->dk_xlen = 0; 718 if (dkp->dk_curout) { 719 mbp = mtod(dkp->dk_curout, struct mpacket *); 720 if (mbp->mp_endfcn) 721 (mbp->mp_endfcn)(mbp->mp_endparm, dkp-dkit); 722 m_freem(dkp->dk_curout); 723 dkp->dk_curout = NULL; 724 } 725 while (1) { 726 IF_DEQUEUE(&dkp->dk_outq, m); 727 if (!m) break; 728 mbp = mtod(m, struct mpacket *); 729 if (mbp->mp_endfcn) 730 (mbp->mp_endfcn)(mbp->mp_endparm, dkp-dkit); 731 m_freem(m); 732 } 733 dkp->dk_state &= ~DK_BUSY ; 734 } 735 if ((dkp->dk_state & DK_OPEN) && (rwflag >= 0)) { 736 register struct dkpkbufr *dbp ; 737 738 dkp->dk_rlen = 0 ; 739 dkp->dk_xlen = 0 ; 740 dkp->dk_C = 0 ; 741 while (dbp = dkp->dk_rq) { 742 dkp->dk_rq = dbp->Pnext ; 743 dbp->Pnext = dk_Sfree ; 744 dk_Sfree = dbp ; 745 } 746 while (dbp = dkp->dk_rb) { 747 dkp->dk_rb = dbp->Pnext ; 748 dbp->Pnext = dk_Sfree ; 749 dk_Sfree = dbp ; 750 } 751 } 752 splx(s) ; 753 } 754 755 756 /* 757 * Routine to handle completion status 758 */ 759 static 760 dkkint() 761 { 762 register struct dkchan *dkp; 763 register struct dkstat *sp; 764 register chan; 765 struct mbuf *m ,*om; 766 struct mpacket *mbp; 767 static char *cmpltype[] = {"send", "rdb", "eoi", "cntl", "err"}; 768 769 while (Tstat != Hstat) { 770 sp = &dkdr_stat[Hstat]; 771 chan = sp->k_chan; 772 dkp = &dkit[chan]; 773 if (sp->k_chan > dkdebug) { 774 if (sp->k_type >= KS_SEND && sp->k_type <= KS_ERR) 775 log(LOG_ERR, "dkdone: type %s chan %d info %o-%o\n", 776 cmpltype[sp->k_type-KS_SEND], 777 sp->k_chan, sp->k_info1, sp->k_info2) ; 778 else log(LOG_ERR, "dkdone: type %d chan %d info %o-%o\n", 779 sp->k_type, sp->k_chan, sp->k_info1, sp->k_info2) ; 780 } 781 if (Hstat==dkdr_nstat-1) Hstat=0; else Hstat++; 782 switch(sp->k_type) { 783 case KS_CNTL: 784 if (dkp->dk_supfcn) 785 (*dkp->dk_supfcn)(chan, sp->k_info1) ; 786 break ; 787 case KS_EOI: 788 break ; 789 case KS_SEND: 790 om = dkp->dk_curout ; 791 if (om == NULL) { 792 log(LOG_ERR, "dkk: xbufout\n"); 793 break; 794 } 795 IF_DEQUEUE(&dkp->dk_outq, m); 796 if (m == NULL) { 797 dkp->dk_state &= ~DK_BUSY; 798 dkp->dk_curout = NULL; 799 } else { 800 dkp->dk_curout = m; 801 mbp = mtod(m, struct mpacket *); 802 dkp->dk_xlen = mbp->mp_len ; 803 if (chan > dkdebug) 804 log(LOG_ERR, "xmiti %d: %x len %d\n", chan, 805 m->m_next, mbp->mp_len) ; 806 dkxmit(dkp, chan, 0) ; 807 } 808 mbp = mtod(om, struct mpacket *); 809 if (mbp->mp_endfcn != NULL) 810 (mbp->mp_endfcn)(mbp->mp_endparm, chan) ; 811 m_freem(om); 812 break; 813 case KS_RDB: 814 dkp->dk_state &= ~(DK_RCV|DK_RCVQ) ; 815 if (sp->k_info2 == DKR_TIME && dkp->dk_rlen == 0) 816 break ; /* another coming later */ 817 if (dkp->dk_rlen) { 818 sp->k_info1 = dkp->dk_rlen ; 819 dkp->dk_rlen = 0 ; 820 } 821 if (dkp->dk_endfcn != NULL) 822 (*dkp->dk_endfcn)(dkp->dk_endparm, dkp-dkit, sp->k_info1, sp->k_info2&0377, 823 (sp->k_info2>>8)&0377) ; 824 break; 825 case KS_ERR: 826 log(LOG_ERR, "err in dkit.c: chan - %d, code - %o\n", 827 chan, sp->k_info1); 828 break; 829 } /* end switch */ 830 831 } /* end while */ 832 } 833 834 835 836 837 838 839 840 /* static */ 841 int dkxmitpanic = 0; 842 843 dkxmit(dkp, stechan, intrpt) 844 struct dkchan *dkp ; 845 { 846 register struct rdevice *raddr ; 847 register char *ptr ; 848 register struct mbuf *m; 849 register int wtype; 850 short pklen ; 851 short mlen, unacked ; 852 short blklen ; 853 unsigned short totlen ; 854 struct mpacket *mbp ; 855 #ifdef notdef 856 short scheck ; 857 #endif 858 859 if( dkp->dk_curout == NULL || stechan ==0 ) 860 return ; 861 mbp = mtod(dkp->dk_curout, struct mpacket *); 862 raddr = DKADDR ; 863 if ((dkp->dk_S & DKBMASK) == (dkp->dk_R & DKBMASK) || (dkp->dk_state & DK_SPND)) 864 goto ctlchk ; 865 if ((dkp->dk_xlen || ((mbp->mp_ctl & 0200) == 0)) && dkp->dk_X < XM_INIT) 866 goto ctlchk ; 867 #ifdef notdef 868 if ((dkp->dk_S & DKBMASK) == ((dkp->dk_R + 1) & DKBMASK)) 869 scheck = 0 ; 870 else 871 scheck = 1 ; 872 #endif 873 874 unacked = ((dkp->dk_S - dkp->dk_A - 1) & 07) * DKBLOCK ; 875 mlen = MIN(unacked, dkp->dk_xlen) ; 876 totlen = dkp->dk_xlen - mlen; 877 if (totlen == 0) 878 goto ctlchk ; 879 880 /* Skip over stuff sent but not acked */ 881 for (m = dkp->dk_curout->m_next; m && (mlen > 0); m = m->m_next) 882 if (mlen > m->m_len) mlen -= m->m_len; 883 else break; 884 885 while (totlen && ((dkp->dk_S ^ dkp->dk_R) & DKBMASK)) { 886 if (dkxmitpanic) panic("dkxmit -- panic 1"); 887 blklen = MIN (totlen, DKBLOCK) ; 888 pklen = 0 ; 889 raddr->dkcsr = D_WRITE ; 890 raddr->dko = stechan | DKMARK ; 891 while (blklen) { 892 if (dkxmitpanic) panic("dkxmit -- panic 2"); 893 if (m == NULL) panic("dkxmit mlen"); 894 ptr = mtod(m, char *) + mlen; 895 mlen = MIN(blklen, m->m_len - mlen); 896 blklen -= mlen; 897 wtype = (m->m_type == DKMT_CTL ? 0 : DKDATA); 898 while (mlen--) { 899 if (dkxmitpanic) panic("dkxmit -- panic 3"); 900 raddr->dko = (*ptr++ & 0377) | wtype ; 901 pklen++ ; 902 if ((pklen & (DKCHUNK-1)) == 0) { 903 raddr->dkcsr = D_XPACK ; 904 raddr->dko = 0 ; 905 raddr->dkcsr = D_WRITE ; 906 raddr->dko = stechan|DKMARK ; 907 } 908 } 909 if (ptr == (mtod(m, char *) + m->m_len)) { 910 m = m->m_next; 911 mlen = 0; 912 } 913 else mlen = ptr - mtod(m, char *); 914 } 915 blklen = MIN (totlen, DKBLOCK) ; 916 if ((pklen & (DKCHUNK-1)) > (DKCHUNK-4)) { 917 raddr->dkcsr = D_XPACK ; 918 raddr->dko = 0 ; 919 raddr->dkcsr = D_WRITE ; 920 raddr->dko = stechan|DKMARK ; 921 } 922 if (blklen == totlen && mbp->mp_eob) 923 raddr->dko = BOT ; 924 else 925 raddr->dko = BOTM ; 926 raddr->dko = (blklen & 0377) | DKDATA ; 927 raddr->dko = ((blklen>>8) & 0377) | DKDATA ; 928 raddr->dko = SEQ + dkp->dk_S ; 929 raddr->dkcsr = D_XPACK ; 930 raddr->dko = 0 ; 931 URPTRACE(stechan, SEQ + dkp->dk_S, dkp); 932 dkp->dk_S++ ; 933 dkp->dk_S &= 07 ; 934 totlen -= blklen ; 935 } 936 #ifdef notdef 937 if (totlen == 0 && dkp->dk_xlen && scheck) { 938 raddr->dkcsr = D_WRITE ; 939 raddr->dko = stechan|DKMARK ; 940 raddr->dko = CHECK ; 941 raddr->dkcsr = D_XPACK ; 942 raddr->dko = 0 ; 943 URPTRACE(stechan, CHECK, dkp); 944 } 945 #endif 946 ctlchk: 947 if (mbp->mp_ctl & 0200) { 948 raddr->dkcsr = D_WRITE ; 949 raddr->dko = stechan|DKMARK ; 950 raddr->dko = mbp->mp_ctl & 0377 ; 951 raddr->dkcsr = D_XPACK ; 952 raddr->dko = 0 ; 953 mbp->mp_ctl = 0 ; 954 if (dkp->dk_xlen == 0) 955 dkreport(KS_SEND, stechan, 0, 0, intrpt) ; 956 } 957 if(dkdisabled) 958 raddr->dkcsr = 0; 959 else 960 raddr->dkcsr = ENABS ; 961 } 962 963 964 static 965 dkrcv(dkp, stechan, intrpt) 966 struct dkchan *dkp ; 967 { 968 register char *ptr1 ; 969 register char *ptr2 ; 970 register len ; 971 short final ; 972 short hibits ; 973 struct dkpkbufr *pkb ; 974 short tlen ; 975 976 if ((dkp->dk_rlen == 0) || (dkp->dk_rq == NULL)) 977 return ; 978 final = 0 ; 979 tlen = 0 ; 980 while (final == 0 && (pkb = dkp->dk_rq)) { 981 if (dkp->dk_rlen == 0) 982 final |= DKR_FULL ; 983 ptr1 = &pkb->Pdata[0] ; 984 ptr2 = dkp->dk_raddr ; 985 len = MIN(pkb->Plen, dkp->dk_rlen) ; 986 hibits = pkb->Phibits ; 987 while (len--) { 988 if (hibits < 0) 989 break ; 990 hibits <<= 1 ; 991 *ptr2++ = *ptr1++ ; 992 } 993 len = ptr2 - dkp->dk_raddr ; 994 tlen += len ; 995 dkp->dk_rlen -= len ; 996 dkp->dk_raddr = ptr2 ; 997 if ((pkb->Plen -= len) && hibits < 0) { 998 final |= ((*ptr1++ & 0377) << 8) | DKR_CNTL ; 999 hibits <<= 1 ; 1000 pkb->Plen-- ; 1001 } 1002 if (len = pkb->Plen) { 1003 ptr2 = &pkb->Pdata[0] ; 1004 while (len--) 1005 *ptr2++ = *ptr1++ ; 1006 pkb->Phibits = hibits ; 1007 } 1008 while (pkb && (pkb->Plen == 0)) { 1009 if ((pkb->Pseq & 0370) == ACK) { 1010 pkb->Pseq += ECHO - ACK ; 1011 final |= dkp->dk_rmode & DKR_BLOCK ; 1012 } 1013 if (pkb->Pseq) { 1014 dksend(stechan, pkb->Pseq) ; 1015 dkp->dk_C = pkb->Pseq ; 1016 } 1017 dkp->dk_rq = pkb->Pnext ; 1018 pkb->Pnext = dk_Sfree ; 1019 dk_Sfree = pkb ; 1020 pkb = dkp->dk_rq ; 1021 } 1022 } 1023 if (tlen && (dkp->dk_rmode & DKR_TIME)) 1024 final |= DKR_TIME ; 1025 if (dkp->dk_rlen == 0) 1026 final |= DKR_FULL ; 1027 if (final && (final != DKR_TIME || ((dkp->dk_state & DK_RCVQ) == 0))) { 1028 dkp->dk_state |= DK_RCVQ ; 1029 len = dkp->dk_rlen ; 1030 if (final != DKR_TIME) 1031 dkp->dk_rlen = 0 ; 1032 dkreport(KS_RDB, stechan, len, final, (final == DKR_TIME)?2:intrpt) ; 1033 } 1034 } 1035 1036 1037 1038 static 1039 dksend(stechan, val) 1040 { 1041 register struct rdevice *raddr ; 1042 register savcsr ; 1043 1044 if(stechan == 0) 1045 return; 1046 1047 raddr = DKADDR ; 1048 savcsr = raddr->dkcsr ; 1049 raddr->dkcsr = D_WRITE ; 1050 raddr->dko = stechan| DKMARK ; 1051 raddr->dko = val ; 1052 raddr->dkcsr = D_XPACK ; 1053 raddr->dko = 0 ; 1054 raddr->dkcsr = savcsr ; 1055 } 1056 1057 1058 /*ARGSUSED*/ 1059 dkdrrint(dev) /* ?? */ /* needed for UNIX OS */ 1060 { 1061 register struct rdevice *raddr ; 1062 register c ; 1063 register cnt; 1064 1065 #ifdef lint 1066 c = 0; cnt = c; 1067 #endif 1068 cnt = 0; 1069 raddr = DKADDR ; 1070 raddr->dkcsr = D_OSEQ ; 1071 if((raddr->dkcsr & DKTDONE) == 0){ 1072 if(dkstray++ >= MAX_STRAY){ 1073 log(LOG_ERR, "DK err 1 (Cabling?)\n"); 1074 raddr->dkcsr = 0; 1075 dkdisabled = 1; 1076 return; 1077 } 1078 } 1079 while (raddr->dkcsr & DKTDONE){ 1080 c = raddr->dki ; 1081 if(cnt++ > 65){ 1082 log(LOG_ERR, "DK err 2 (Cabling?)\n"); 1083 raddr->dkcsr = 0; 1084 dkdisabled = 1; 1085 return; 1086 } 1087 } 1088 raddr->dkcsr = ENABS ; 1089 if (Hstat != Tstat) 1090 dkkint() ; 1091 } 1092 1093 /*ARGSUSED*/ 1094 dkdrxint(dev) /* ?? */ 1095 { 1096 register struct rdevice *raddr ; 1097 register char *ptr ; 1098 struct dkchan *dkp ; 1099 register c ; 1100 short badpacks ; 1101 struct dkpkbufr *pkb ; 1102 short stechan ; 1103 short len, xlen ; 1104 unsigned short bitloc ; 1105 1106 badpacks = 0 ; 1107 raddr = DKADDR ; 1108 pkb = NULL ; 1109 if(raddr->dkcsr >= 0){ 1110 if(dkstray++ > MAX_STRAY){ 1111 log(LOG_ERR, "DK err 3 (Cabling?)\n"); 1112 goto disable; 1113 } 1114 } 1115 while (raddr->dkcsr < 0) { 1116 raddr->dkcsr = D_READ ; 1117 c = raddr->dki ; 1118 while (raddr->dkcsr < 0 && (c & DKMARK)) { 1119 c &= 0777 ; 1120 if (c >= dk_nchan) { 1121 if (++badpacks > 20) { 1122 log(LOG_ERR, "DK err 4 (Cabling?)\n"); 1123 dkreport(KS_ERR, 0, 2, 0, 1) ; 1124 goto disable ; 1125 } 1126 break ; 1127 } 1128 /* discard all chl 0 packets; 1129 * the LDI version of the CPM-DR and CPM-422 1130 * puts out packets on chl 0 occasionally. 1131 */ 1132 if(c == 0) break; 1133 1134 dkp = &dkit[c] ; 1135 stechan = c ; 1136 qpkb: 1137 if (pkb && pkb->Plen) { 1138 dkrcvq(stechan, dkp, pkb, 0) ; 1139 pkb = NULL ; 1140 } 1141 if (pkb == NULL) { 1142 if ((pkb = dk_Sfree) != NULL) { 1143 dk_Sfree = pkb->Pnext ; 1144 pkb->Pseq = 0 ; 1145 pkb->Plen = 0 ; 1146 pkb->Pnext = NULL ; 1147 pkb->Phibits = 0 ; 1148 } else { 1149 /* 1150 ** Oops, no more dkpkbufr's. 1151 ** Let outer loop gobble up 1152 ** the entire packet. 1153 ** Report to the console 1154 ** every 100th occurrence. 1155 */ 1156 if ( dknopkb++ >= 100 ) { 1157 dknopkb = 1 ; 1158 dkreport(KS_ERR, 0, 3, 0, 1) ; 1159 } 1160 break ; 1161 } 1162 } 1163 raddr->dkcsr = D_READ ; 1164 ptr = &pkb->Pdata[0] ; 1165 bitloc = 0100000 ; 1166 while (raddr->dkcsr < 0 && ((c = raddr->dki) & DKMARK) == 0) 1167 switch (c = c & 0777) { 1168 case NULL: 1169 break ; 1170 case AINIT: 1171 dkp->dk_X = XM_INIT ; 1172 dkp->dk_R = 0 ; 1173 dkp->dk_S = 1 ; 1174 dkp->dk_A = 0 ; 1175 dkxmit(dkp, stechan, 1) ; 1176 raddr->dkcsr = D_READ ; 1177 break ; 1178 case INIT0: 1179 dksend(stechan, AINIT) ; 1180 dkp->dk_trmode = 0 ; 1181 dkp->dk_C = dkp->dk_rseq = 0 ; 1182 break ; 1183 case INIT1: 1184 dksend(stechan, AINIT) ; 1185 dkp->dk_trmode = 1 ; 1186 dkp->dk_C = dkp->dk_tail1 = dkp->dk_tail2 = dkp->dk_rseq = 0 ; 1187 while (pkb) { 1188 pkb->Pnext = dk_Sfree ; 1189 dk_Sfree = pkb ; 1190 if (pkb = dkp->dk_rq) 1191 dkp->dk_rq = pkb->Pnext ; 1192 if (pkb == NULL) 1193 if (pkb = dkp->dk_rb) 1194 dkp->dk_rb = pkb->Pnext ; 1195 } 1196 goto qpkb ; 1197 case INITREQ: 1198 dksend(stechan, INIT1) ; 1199 dkp->dk_X = 0 ; 1200 break ; 1201 case ENQ: 1202 dksend(stechan, dkp->dk_C) ; 1203 case CHECK: 1204 dksend(stechan, ACK+dkp->dk_rseq) ; 1205 while (pkb) { 1206 pkb->Pnext = dk_Sfree ; 1207 dk_Sfree = pkb ; 1208 if (pkb = dkp->dk_rb) 1209 dkp->dk_rb = pkb->Pnext ; 1210 } 1211 dkp->dk_rblen = 0 ; 1212 goto qpkb ; 1213 case EOI: 1214 if (dkp->dk_tail1 == ((SOI<<8)|2)) 1215 dkreport(KS_EOI, stechan, dkp->dk_tail2, 0, 1) ; 1216 dkp->dk_tail1 = 0 ; 1217 break ; 1218 default: 1219 if (c & DKDATA) { 1220 if (dkp->dk_tail1) { 1221 dkp->dk_tail2 = ((dkp->dk_tail2 >> 8) & 0377) | (c<<8) ; 1222 dkp->dk_tail1++ ; 1223 if ((dkp->dk_tail1 & 0377) > 3) 1224 dkp->dk_tail1 = 0 ; 1225 } else { 1226 *ptr++ = c & 0377 ; 1227 pkb->Plen++ ; 1228 bitloc >>= 1 ; 1229 } 1230 break ; 1231 } 1232 if (((c & 0770) == ECHO) || ((c & 0770) == REJ)) { 1233 URPTRACE(stechan, c, dkp); 1234 dkp->dk_R = c & 07 ; 1235 if (((dkp->dk_S - dkp->dk_R - 1) & 07) < 1236 ((dkp->dk_S - dkp->dk_A - 1) & 07)) { 1237 gotack: 1238 dkp->dk_X &= ~(XM_REJ | XM_ENQ); 1239 xlen = dkp->dk_xlen ; 1240 len = ((c - dkp->dk_A) & 07) * DKBLOCK ; 1241 len = MIN(len, xlen); 1242 dkp->dk_xlen -= len; 1243 if (dkp->dk_curout) 1244 m_adj(dkp->dk_curout->m_next, len) ; 1245 dkp->dk_A = c & 07 ; 1246 if (len || xlen) 1247 if ((dkp->dk_xlen) == 0) 1248 dkreport(KS_SEND, stechan, 0, 0, 1) ; 1249 } 1250 dkxmit(dkp, stechan, 1) ; 1251 raddr->dkcsr = D_READ ; 1252 if ((c & 0770) == REJ && ((dkp->dk_X & XM_REJ) == 0)) { 1253 dkp->dk_rejcnt++; 1254 gotrej: 1255 dkp->dk_S = (c+1) & 07 ; 1256 dkxmit(dkp, stechan, 1) ; 1257 raddr->dkcsr = D_READ ; 1258 dkp->dk_X |= XM_REJ ; 1259 } 1260 break ; 1261 } 1262 if ((c & 0770) == ACK) { 1263 URPTRACE(stechan, c, dkp); 1264 if (dkp->dk_A != (c & 07)) 1265 goto gotack ; 1266 if ((dkp->dk_X & XM_REJ) == 0) { 1267 dkp->dk_ackrejcnt++; 1268 goto gotrej ; 1269 } 1270 break ; 1271 } 1272 if ((c & 0774) == BOT) { 1273 dkp->dk_tail1 = c << 8 ; 1274 break ; 1275 } 1276 if ((c & 0770) == SEQ) { 1277 pkb->Pseq = c - SEQ + ECHO ; 1278 dkrcvq(stechan, dkp, pkb, 0) ; 1279 if (dkp->dk_trmode) { 1280 if (dkp->dk_rblen == dkp->dk_tail2 && 1281 (dkp->dk_tail1 & 0377) == 2 && 1282 ((dkp->dk_tail1 >> 8) & 0377) != SOI && 1283 ((dkp->dk_rseq+1) & 07) == (c & 07)) { 1284 dkp->dk_rseq = c & 07 ; 1285 if (((dkp->dk_tail1>>8) & 0377) != BOTM) 1286 pkb->Pseq += ACK - ECHO ; 1287 dkrcvq(stechan, dkp, dkp->dk_rb, 1) ; 1288 } else { 1289 while (pkb = dkp->dk_rb) { 1290 dkp->dk_rb = pkb->Pnext ; 1291 pkb->Pnext = dk_Sfree ; 1292 dk_Sfree = pkb ; 1293 } 1294 pkb = dk_Sfree ; 1295 dk_Sfree = pkb->Pnext ; 1296 pkb->Plen = 0 ; 1297 pkb->Pnext = NULL ; 1298 pkb->Pseq = REJ + dkp->dk_rseq ; 1299 dkp->dk_srejcnt++; 1300 if (((dkp->dk_tail1>>8) & 0377) == BOTS) { 1301 dkp->dk_rseq = c & 07 ; 1302 pkb->Pseq = ECHO + dkp->dk_rseq ; 1303 } 1304 dkrcvq(stechan, dkp, pkb, 1) ; 1305 } 1306 dkp->dk_rb = NULL ; 1307 dkp->dk_rblen = 0 ; 1308 dkp->dk_tail1 = 0 ; 1309 } else 1310 /* always keep seq no up to date */ 1311 dkp->dk_rseq = c & 07; 1312 pkb = NULL ; 1313 goto qpkb ; 1314 } 1315 if (c & 0200) { 1316 dkreport(KS_CNTL, stechan, c, 0, 1) ; 1317 raddr->dkcsr = D_READ ; 1318 } else { 1319 *ptr++ = c & 0377 ; 1320 pkb->Plen++ ; 1321 pkb->Phibits |= bitloc ; 1322 bitloc >>= 1 ; 1323 } 1324 } 1325 if (pkb && pkb->Plen) { 1326 dkrcvq(stechan, dkp, pkb, 0) ; 1327 pkb = NULL ; 1328 } 1329 } 1330 } 1331 1332 if (pkb) { 1333 if (pkb->Plen) 1334 dkrcvq(stechan, dkp, pkb, 0) ; 1335 else { 1336 pkb->Pnext = dk_Sfree ; 1337 dk_Sfree = pkb ; 1338 } 1339 } 1340 raddr->dkcsr = ENABS ; 1341 return; 1342 1343 disable: 1344 if(pkb){ 1345 pkb->Pnext = dk_Sfree; 1346 dk_Sfree = pkb; 1347 } 1348 raddr->dkcsr = 0; 1349 dkdisabled = 1; 1350 } 1351 1352 dkrcvq(stechan, dkp, npkb, where) 1353 register struct dkchan *dkp ; 1354 struct dkpkbufr *npkb ; 1355 { 1356 register struct dkpkbufr *pkb ; 1357 int i ; 1358 1359 i = 0 ; 1360 if (dkp->dk_trmode && where == 0) 1361 pkb = (struct dkpkbufr *)&dkp->dk_rb ; 1362 else 1363 pkb = (struct dkpkbufr *)&dkp->dk_rq ; 1364 1365 while (pkb->Pnext) { 1366 pkb = pkb->Pnext ; 1367 i++ ; 1368 } 1369 if ( i >= PKBHOG ) { 1370 /* 1371 ** This channel has too many buffers. 1372 ** Do not queue any more. 1373 ** Return the new buffer to the free list. 1374 */ 1375 npkb->Pnext = dk_Sfree ; 1376 dk_Sfree = npkb ; 1377 return ; 1378 } 1379 pkb->Pnext = npkb ; 1380 1381 if (dkp->dk_trmode && where == 0) 1382 dkp->dk_rblen += npkb->Plen ; 1383 else 1384 dkrcv(dkp, stechan, 1) ; 1385 } 1386 1387 1388 1389 dkreport(type, chan, info1, info2, intrpt) 1390 /* intrpt parameter controlls whether the pdp-11 interrupt is called. 1391 * Value 0 says no (means dkxint queued already) 1392 * Value 1 says call it immediately (like from dr11c interrupt) 1393 * Value 2 says to queue a call as soon as processor priority lowers 1394 * (by sending a dummy packet on a channel and getting dkxint) 1395 */ 1396 { 1397 register struct dkstat *sp; 1398 1399 if ((Tstat + 1) % dkdr_nstat == Hstat) { /* room in queue? */ 1400 log(LOG_ERR, "dkit_dr: No room in status queue, Channel %d\n", chan); 1401 return; 1402 } 1403 1404 sp = &dkdr_stat[Tstat] ; 1405 sp->k_chan = chan ; 1406 sp->k_type = type ; 1407 sp->k_info1 = info1 ; 1408 sp->k_info2 = info2 ; 1409 if (Tstat == dkdr_nstat-1) Tstat = 0 ; else Tstat++ ; 1410 if (intrpt==1) { 1411 dkkint() ; 1412 } else if (intrpt==2) { 1413 register struct rdevice *raddr ; 1414 raddr = DKADDR ; 1415 raddr->dkcsr = D_WRITE ; 1416 1417 /* Chl (dk_nchan-1) is used instead of 511 because 1418 * the LDI switch module will complain if we use 1419 * a chl outside the range set up in its route tables. 1420 */ 1421 raddr->dko = (dk_nchan-1) | DKMARK ; 1422 1423 /* 1424 * A null is used here because it should always 1425 * be ignored by the far end of the circuit. 1426 */ 1427 raddr->dko = 0 ; 1428 1429 raddr->dkcsr = D_XPACK ; 1430 raddr->dko = 0 ; 1431 raddr->dkcsr = ENABS ; 1432 } 1433 } 1434 1435 #ifdef URPDEBUG 1436 struct dkurps { 1437 char dku_ctl; 1438 char dku_S; 1439 char dku_R; 1440 char dku_A; 1441 } dkurps[URPDEBUG]; 1442 int dkurpsize = URPDEBUG; 1443 1444 struct dkurps *dkurpsp = dkurps; 1445 int dkurpreset; 1446 1447 dkurptrace(ctl, dkp) char ctl; register struct dkchan *dkp; 1448 { 1449 #ifdef lint 1450 dkurpsize = dkurpsize; 1451 #endif 1452 if (dkurpreset) { 1453 dkurpsp = dkurps; 1454 dkurpreset = 0; 1455 } 1456 dkurpsp->dku_ctl = ctl; 1457 dkurpsp->dku_S = dkp->dk_S; 1458 dkurpsp->dku_R = dkp->dk_R; 1459 dkurpsp->dku_A = dkp->dk_A; 1460 if (++dkurpsp == dkurps+URPDEBUG) 1461 dkurpsp = dkurps; 1462 } 1463 #endif URPDEBUG 1464 #endif 1465