1 /* 2 * Datakit driver 3 * KMC assistance, with or without DR11C 4 */ 5 6 #include "dkitkmc.h" 7 #if NDKITKMC>0 8 9 #include "datakit.h" 10 11 #include "../machine/pte.h" 12 #include "param.h" 13 #include "syslog.h" 14 #include "time.h" 15 #include "kernel.h" 16 #include "buf.h" 17 #include "mbuf.h" 18 #include "errno.h" 19 #include "socket.h" 20 #include "../net/if.h" 21 #include "../vaxif/if_uba.h" 22 #include "../vaxuba/ubareg.h" 23 #include "../vaxuba/ubavar.h" 24 25 #include "dkit.h" 26 #include "dkkmc.h" 27 #include "dk.h" 28 29 #define KMXSMALL 0 30 #define KMXBIG 1 31 32 #define MONITOR 1 33 34 #ifdef MONITOR 35 static int dummy ; 36 int *DKP = &dummy ; 37 #define M_ON(a) *DKP |= (a) 38 #define M_OFF(a) *DKP &= ~(a) 39 #define M_TRACE(a) *DKP |= (a);*DKP &= ~(a) 40 41 #define Mxmit 01 42 #define Mrecv 02 43 #define Mkint 04 44 #define Mint 010 45 #define Mcmd 020 46 47 #else 48 #define M_ON(a) 49 #define M_OFF(a) 50 #define M_TRACE(a) 51 #endif 52 53 extern int dk_nchan; 54 55 struct dkchan dkit[NDATAKIT]; 56 57 #define DKNCMDB 20 58 #define DKNSTB 20 59 60 int dkk_ncmd = DKNCMDB; 61 struct dkkin dkkcmdbuf[DKNCMDB]; 62 int dkk_nstat = DKNSTB; 63 struct dkkin dkkstat[DKNSTB]; 64 char dkkbuf[16*1024]; 65 int dkubmbuf; 66 67 static struct kdevice *dkkaddr; 68 69 /* 70 * initial information to the KMC 71 */ 72 struct dkinit { 73 caddr_t cmdaddr; /* command buffer */ 74 caddr_t stataddr; /* status buffer */ 75 caddr_t bufaddr ; /* kmc workspace */ 76 caddr_t csraddr; /* for KMC/DR DR register address */ 77 } dkkmcinit; 78 79 /* 80 * structure of data in first mbuf on chain (type DKM_HDR) 81 * 82 */ 83 struct mpacket { 84 short mp_len; /* Total length left */ 85 char mp_ctl; /* Control character */ 86 int mp_eob; /* Send end-of-block indicator */ 87 int (*mp_endfcn)(); /* End-action function */ 88 caddr_t mp_endparm; /* Parameter to above function */ 89 }; 90 91 92 /* 93 * The circular buffer, cmdbuf, is used to pass command to kmc: 94 * while the circular buffer statbuf is used to report status. 95 * There are 8 control and status registers (csr) accessible to 96 * both cpu and kmc. 97 * Csr4-csr5 are used to indicate the head and tail respectively 98 * of the cmdbuf. Likewise, csr6-csr7 for statbuf. 99 * At initialization time, the cpu and kmc would agree on the beginning 100 * address of both buffers and their sizes. 101 */ 102 #define csr0 dkkaddr->un.bsel.bsel0 /* kmc state */ 103 #define csr1 dkkaddr->un.bsel.bsel1 104 #define csr2 dkkaddr->un.bsel.bsel2 /* used at init time, to pass */ 105 #define csr3 dkkaddr->un.bsel.bsel3 /* addresses to the kmc */ 106 #define csr4 dkkaddr->un.bsel.bsel4 /* head cmdbuf */ 107 #define csr5 dkkaddr->un.bsel.bsel5 /* tail cmdbuf */ 108 #define csr6 dkkaddr->un.bsel.bsel6 /* head statbuf */ 109 #define csr7 dkkaddr->un.bsel.bsel7 /* tail statbuf */ 110 111 112 /* 113 * kmc device registers 114 */ 115 struct kdevice { 116 union { 117 struct { short sel0, sel2, sel4, sel6;} wsel ; 118 struct { char bsel0, bsel1, bsel2, bsel3; 119 char bsel4, bsel5, bsel6, bsel7; } bsel ; 120 } un; 121 }; 122 123 124 /* 125 * For the moment, only support one kmc (kmc0) 126 * More need be done for multiple kmc's 127 */ 128 129 int dkdebug = 512 ; 130 int dkactive = 0 ; 131 int dkbindex ; 132 static int kseqchk = 0; /* used to check seq. #'s in statbuf */ 133 static int dkpanic = 0; /* # of dk_close(0)'s in this run */ 134 static int kseq = 0; /* # kmc responses mod 0377 */ 135 static int pseq = 0; 136 137 static struct dkkin *cmd4; /* dkkcmdbuf[csr4] pointer */ 138 static struct dkkin *stat7; /* dkkstat[csr7] pointer */ 139 140 int dkk_cnt ; 141 static struct uba_device *ui; 142 143 dkkmc_attach(kui) struct uba_device *kui; 144 { 145 ui = kui; 146 dkk_cnt = kui->ui_unit; 147 } 148 149 dk_init() 150 { 151 int t, kt ; 152 extern dkkint() ; 153 154 /* 155 * On the first open of the hardware interface 156 */ 157 if (!ui) return -ENXIO; 158 if (kmcset((dkk_cnt)<<6,03,dkkint)) { 159 /* debug */ log(LOG_ERR, "dkkmcinit bad: kmcset failed\n"); 160 return -1; 161 } 162 dkkaddr = ((struct kdevice *) ui->ui_addr); 163 164 /* if csr0 != 0, then error 165 else pass the address of struct init 166 in csr2~4 and set csr0 to 1 */ 167 168 if ((csr0 & 3) != 0) { 169 /* debug */ log(LOG_ERR, "dkkmcinit: csr0 != 0\n"); 170 return EIO; 171 } 172 173 /* Map UBA registers to point to our stuff */ 174 kt = dk_ubainit(); 175 if (kt == 0) { 176 log(LOG_ERR, "dkkmcinit: no uba resources\n"); 177 return ENOBUFS; 178 } 179 180 /* Address of DR11-C (if any) */ 181 t = ui->ui_flags & ~03 ; 182 dkkmcinit.csraddr = (caddr_t) ((t<<16) + 3) ; /* bits 17 + 18 must be 1 */ 183 184 /* append new init info here, if it is needed */ 185 186 dkkaddr->un.wsel.sel2 = (short)(kt & 0xFFFF); /* bits 0-15 */ 187 dkkaddr->un.bsel.bsel4 = (char)((kt & 0xFF0000) >> 16); /* bits 16-23 */ 188 189 csr0 = 1; /* tell KMC to read csr2 */ 190 kseq = 0 ; 191 192 cmd4 = &dkkcmdbuf[0] ; /* driver's pointers into cmdbuf and statbuf */ 193 stat7 = &dkkstat[0] ; 194 dkactive = 1 ; 195 return 0 ; 196 } 197 198 int dk_ubaed = 0; 199 200 dk_ubainit() 201 { 202 int t; 203 static int kt; 204 205 if (dk_ubaed) { 206 if (dkdebug < dk_nchan) 207 log(LOG_ERR, "dk_ubainit: reinit\n"); 208 return kt; 209 } 210 dk_ubaed = 1; 211 212 /* Initialization buffer */ 213 kt = uballoc(ui->ui_ubanum, (caddr_t) &dkkmcinit, sizeof dkkmcinit, UBA_CANTWAIT); 214 if (kt == 0) return 0; 215 216 /* Command input buffer */ 217 t = uballoc(ui->ui_ubanum, (caddr_t) dkkcmdbuf, sizeof dkkcmdbuf, UBA_CANTWAIT) ; 218 if (t == 0) return 0; 219 dkkmcinit.cmdaddr = (caddr_t) ((t<<16) + ((t>>16) & 03)); /* must swap bytes for unibus */ 220 221 /* Status out buffer */ 222 t = uballoc(ui->ui_ubanum, (caddr_t) dkkstat, sizeof dkkstat, UBA_CANTWAIT); 223 if (t == 0) return 0; 224 dkkmcinit.stataddr = (caddr_t) ((t<<16) + ((t>>16) & 03)); 225 226 /* KMC buffer */ 227 dkubmbuf = uballoc(ui->ui_ubanum, (caddr_t) dkkbuf, sizeof dkkbuf, UBA_CANTWAIT); 228 if (t == 0) return 0; 229 dkkmcinit.bufaddr = (caddr_t) ((dkubmbuf<<16) + ((dkubmbuf>>16) & 03)); 230 if (dkdebug < dk_nchan) 231 log(LOG_ERR, "dk_ubainit: bufaddr %x mapped %x\n", (caddr_t)dkkbuf, 232 dkubmbuf); 233 234 return kt; 235 } 236 237 dk_open(chan, supfcn) 238 register chan ; 239 int (*supfcn)() ; 240 { 241 register struct dkchan *dkp; 242 register s ; 243 extern dkkint() ; 244 extern int commchan; 245 int init; 246 247 if (chan >= dk_nchan) 248 return -ENXIO ; 249 if (dkactive == -1) /* fail request if reset is in progress */ 250 return(-ENETRESET) ; 251 dkp = &dkit[chan] ; 252 s = splimp() ; 253 /* 254 * Channel 0 (0-3 in ISN) is reserved for maintenance. 255 * An open on channel 0 is interpreted as a request 256 * for an unused channel. Channel 1 (4 in ISN or RADIAN) 257 * is the common supervisory channel. 258 */ 259 if (chan == 0) { 260 chan = commchan+1; /* Start above commchan */ 261 while (1) { 262 dkp = &dkit[chan] ; 263 if (dkp->dk_state == 0) 264 break ; 265 chan++ ; 266 if (chan >= dk_nchan) { 267 splx(s) ; 268 return -EADDRNOTAVAIL ; 269 } 270 } 271 } 272 splx(s) ; 273 274 if (dkactive == 0) 275 if ((init = dk_init()) < 0) 276 return init ; 277 278 /* 279 * On first use of a channel, we must 280 * allocate per-channel UBA resource for transmit. 281 * Some day, when we convert the receivers to use mbufs, 282 * we'll do the same for reads. 283 * Note that these resources can't easily be freed (I think). 284 */ 285 if (!dkp->dk_uba.ifu_uba) { 286 dkp->dk_uba.ifu_flags = UBA_CANTWAIT; 287 if (if_ubaminit(&dkp->dk_uba.ifu_info, ui->ui_ubanum, 0, 288 btoc(CLBYTES), 289 &dkp->dk_uba.ifu_r, 0, 290 &dkp->dk_uba.ifu_xmt, 1) == 0) { 291 log(LOG_ERR, "dkkmc: no ubamap for channel %d\n", chan); 292 return -ENOBUFS; 293 } 294 dkp->dk_outq.ifq_maxlen = 20; 295 } 296 297 /* 298 * Finish setting up dkp struct. 299 */ 300 if ((dkp->dk_state & DK_OPEN) ==0) { 301 dkcmd(KC_XINIT, chan, (caddr_t)0, (unsigned) 0, KMXBIG, 0); 302 flushall(dkp, 0); 303 dkp->dk_state |= DK_OPEN; 304 dkp->dk_state &= ~(DK_LINGR | DK_RESET); 305 dkactive++ ; 306 } 307 dkp->dk_supfcn = supfcn ; 308 return chan ; 309 } 310 311 312 /* 313 * Close a channel: 314 */ 315 316 dk_close(chan) 317 { 318 register struct dkchan *dkp; 319 register s ; 320 int init; 321 322 if (dkkaddr == 0) return(-ENODEV); /* if no init, can't close */ 323 /* ie: can't do dkmaint */ 324 325 s = splimp() ; 326 dkp = &dkit[chan] ; 327 if (chan == 0) { 328 for (dkp = &dkit[1]; dkp < &dkit[dk_nchan]; dkp++) { 329 if (dkp->dk_state & (DK_OPEN|DK_BUSY|DK_RCV)) { 330 dkp->dk_state |= DK_RESET ; 331 flushall(dkp, 0) ; 332 dkp->dk_state = DK_RESET ; 333 } 334 } 335 dkpanic++ ; 336 kseq = 0 ; 337 pseq = 0 ; 338 #ifdef notdef 339 if(dkubmbuf){ /* only deallocate mem if still allocated */ 340 ubarelse(ui->ui_ubanum, &dkubmbuf); 341 dkubmbuf = NULL; 342 } 343 #endif 344 /* wait for protocols to close channels */ 345 dkactive = -1 ; 346 DELAY(4 * hz) ; 347 /* do a dk_free for all channels */ 348 for (dkp = &dkit[1]; dkp < &dkit[dk_nchan]; dkp++) { 349 dkp->dk_state &= ~DK_LINGR ; 350 } 351 dkactive = 0 ; 352 csr0 = 0 ; /* set kmc to idle mode */ 353 if ((init = dk_init()) < 0) { 354 splx(s) ; 355 return init ; 356 } 357 } else { 358 flushall(dkp, 0) ; 359 dkp->dk_state = DK_LINGR ; /* set while UNIXP protocol 360 closes up channel with DK */ 361 } 362 splx(s) ; 363 return 0; 364 } 365 366 367 368 369 /* 370 * Close phase 2 - mark available for reassignment 371 */ 372 dk_free(chan) 373 { 374 if (chan > dkdebug) 375 log(LOG_ERR, "dk_free %d\n", chan) ; 376 dkit[chan].dk_state &= ~(DK_LINGR | DK_RESET); 377 } 378 379 380 /* 381 * Reset a channel 382 * prevents further I/O until close 383 */ 384 dk_reset(chan) 385 { 386 register struct dkchan *dkp ; 387 register s ; 388 389 if (chan > dkdebug) 390 log(LOG_ERR, "dk_reset %d\n", chan) ; 391 s = splimp() ; 392 dkp = &dkit[chan] ; 393 dkp->dk_state |= DK_RESET ; 394 flushall(dkp, 0) ; 395 splx(s) ; 396 } 397 398 399 400 /* 401 * Xmit a short control (interrupt) packet (max 2 bytes) 402 */ 403 dk_xint(chan, intr) 404 { 405 register s ; 406 407 s = splimp() ; 408 dkcmd(KC_SOI, chan, (caddr_t)0, (unsigned) intr, 0, 0) ; 409 splx(s) ; 410 return 0 ; 411 } 412 413 414 /* 415 * Adjust window size 416 */ 417 /*ARGSUSED*/ 418 dk_winsize(chan, win) 419 struct diocxwin *win; 420 { 421 return EINVAL; /* For now... */ 422 } 423 424 425 426 /* 427 * Xmit data on a channel 428 */ 429 dk_xmit(chan, m, eob, ctlchar, endfcn, endparm) 430 struct mbuf *m ; 431 int (*endfcn)() ; 432 caddr_t endparm ; 433 { 434 register struct dkchan *dkp ; 435 short s ; 436 register struct mpacket *mbp ; 437 register struct mbuf *mb; 438 int len; 439 440 M_ON(Mxmit) ; 441 s = splimp() ; 442 dkp = &dkit[chan] ; 443 if ((dkp->dk_state & DK_RESET) || (mb = m_get(M_DONTWAIT,DKMT_HDR)) == NULL) { 444 m_freem(m); 445 splx(s) ; 446 return 0 ; 447 } 448 449 mb->m_len = 0; 450 mbp = mtod(mb, struct mpacket *); 451 mbp->mp_endfcn = endfcn ; 452 mbp->mp_endparm = endparm ; 453 mbp->mp_eob = eob; 454 mbp->mp_ctl = ctlchar; 455 456 if ((dkp->dk_state & DK_BUSY) == 0) { 457 dkp->dk_state |= DK_BUSY ; 458 dkp->dk_obuf = mbp ; 459 mb->m_next = NULL; 460 len = if_wubaput(&dkp->dk_uba, m); 461 dkcmd(KC_SEND, chan, (caddr_t) UBAI_ADDR(dkp->dk_uba.ifu_w.ifrw_info), 462 (unsigned) len, eob ? SBOT : SBOTM, ctlchar) ; 463 splx(s) ; 464 M_OFF(Mxmit) ; 465 return dkp->dk_state ; 466 } 467 468 mb->m_next = m; 469 if (IF_QFULL(&dkp->dk_outq)) { 470 IF_DROP(&dkp->dk_outq); 471 m_freem(mb); 472 } 473 else 474 IF_ENQUEUE(&dkp->dk_outq, mb); 475 splx(s) ; 476 M_OFF(Mxmit) ; 477 return dkp->dk_state ; 478 } 479 480 /* 481 * Receive into a block buffer 482 */ 483 dk_recv(chan, addr, len, mode, endfcn, endparm) 484 int len; 485 int (*endfcn)() ; 486 caddr_t addr, endparm ; 487 { 488 register struct dkchan *dkp ; 489 int s; 490 491 s = splimp() ; 492 M_ON(Mrecv) ; 493 dkp = &dkit[chan] ; 494 if (dkp->dk_state & (DK_RCV | DK_RESET)) { 495 splx(s) ; 496 return(0) ; 497 } 498 dkp->dk_ubmbase = uballoc(ui->ui_ubanum, addr, len, UBA_CANTWAIT); 499 if (dkp->dk_ubmbase == NULL) { 500 splx(s) ; 501 return(0) ; 502 } 503 dkp->dk_state |= DK_RCV ; 504 dkp->dk_endfcn = endfcn ; 505 dkp->dk_endparm = endparm ; 506 dkp->dk_rlen = len; 507 dkcmd(KC_RCVB, chan, (caddr_t) UBAI_ADDR(dkp->dk_ubmbase), (unsigned) len, mode&0377, mode>>8); 508 M_OFF(Mrecv) ; 509 splx(s); 510 return dkp->dk_state ; 511 } 512 513 /* Abort pending receive */ 514 515 516 dk_rabort(chan, nendfcn, nendparm) 517 int (*nendfcn)() ; 518 caddr_t nendparm; 519 { 520 register struct dkchan *dkp ; 521 register s ; 522 523 dkp = &dkit[chan] ; 524 s = splimp() ; 525 if (dkp->dk_state & DK_RCV) { /* cancel outstanding receive */ 526 dkcmd(KC_RCVB, chan, (caddr_t)0, (unsigned) 0, 0, 0) ; 527 dkp->dk_endfcn = nendfcn ; 528 dkp->dk_endparm = nendparm ; 529 } 530 splx(s) ; 531 return dkp->dk_state ; 532 } 533 534 535 536 dk_status(chan) 537 { 538 if (chan >= dk_nchan) 539 return 0 ; 540 return dkit[chan].dk_state ; 541 } 542 543 544 /* 545 * Various control commands to KMC 546 */ 547 dk_cmd(chan, cmd) 548 { 549 register struct dkchan *dkp ; 550 register s ; 551 552 dkp = &dkit[chan] ; 553 if (cmd & (DKC_XINIT|DKC_FLUSH)) { 554 /*for either command do the same thing: 555 * reinit the transmitter and flush any pending output. 556 * NOTE: for the kmc, there is no response to XINIT 557 * and no send complete for flush 558 */ 559 s = splimp() ; 560 dkcmd(KC_XINIT, chan, (caddr_t)0, (unsigned) 0, KMXBIG, 0) ; 561 flushall(dkp, -1) ; 562 dkcmd(KC_CMD, chan, (caddr_t)0, (unsigned) DKC_FLUSH, 0, 0) ; 563 splx(s); 564 cmd &= ~(DKC_XINIT|DKC_FLUSH) ; 565 } 566 if (cmd) 567 dkcmd(KC_CMD, chan, (caddr_t)0, (unsigned) cmd, 0, 0) ; 568 } 569 570 571 /* 572 * Note that flushall is often recursive when a tty driver 573 * is involved. 574 */ 575 576 static 577 flushall(dkp, rwflag) 578 register struct dkchan *dkp ; 579 { 580 register s ; 581 register struct mpacket *mbp ; 582 int (*endfcn)(); 583 584 s = splimp() ; 585 if ((dkp->dk_state & DK_RCV) && (rwflag >= 0)) { 586 dkcmd(KC_RCVB, dkp-dkit, (caddr_t)0, (unsigned) 0, 0, 0) ; 587 dkp->dk_state &= ~DK_RCV ; 588 if (dkp->dk_ubmbase) { 589 ubarelse(ui->ui_ubanum, &dkp->dk_ubmbase); 590 dkp->dk_ubmbase = NULL; 591 } 592 if (endfcn = dkp->dk_endfcn) { 593 dkp->dk_endfcn = NULL ; 594 (*endfcn)(dkp->dk_endparm, dkp-dkit, dkp->dk_rlen, DKR_ABORT, 0) ; 595 } 596 } 597 598 /* flush all writes current and pending */ 599 600 if ((dkp->dk_state & DK_BUSY) && (rwflag <= 0)) { 601 register struct mbuf *m ; 602 603 /* flush current write */ 604 if (mbp = dkp->dk_obuf) { 605 dkp->dk_obuf = NULL; 606 if (endfcn = mbp->mp_endfcn) { 607 mbp->mp_endfcn = NULL; 608 (endfcn)(mbp->mp_endparm, dkp-dkit); 609 } 610 m_free(dtom(mbp)); 611 } 612 /* flush any pending writes which may be queued up */ 613 while (1) { 614 IF_DEQUEUE(&dkp->dk_outq, m); 615 if (!m) break; 616 mbp = mtod(m, struct mpacket *); 617 if (endfcn = mbp->mp_endfcn) { 618 mbp->mp_endfcn = NULL; 619 (endfcn)(mbp->mp_endparm, dkp-dkit); 620 } 621 m_freem(m); 622 } 623 /* mark channel as not busy */ 624 dkp->dk_state &= ~DK_BUSY ; 625 } 626 if ((dkp->dk_state & DK_OPEN) && (rwflag >= 0)) { 627 dkcmd(KC_CLOSE, dkp-dkit, (caddr_t)0, (unsigned) 0, 0, 0) ; 628 if (dkp->dk_state & DK_BUSY){ 629 mbp = dkp->dk_obuf; 630 dkp->dk_obuf = NULL; 631 if (endfcn = mbp->mp_endfcn) { 632 mbp->mp_endfcn = NULL; 633 (endfcn)(mbp->mp_endparm, dkp-dkit); 634 } 635 m_free(dtom(mbp)); 636 dkp->dk_state &= ~DK_BUSY ; 637 } 638 } 639 splx(s) ; 640 } 641 642 643 short dup_count = 0; /* counter for number of duplicate sends */ 644 645 /* 646 * Routine to handle interrupts from the KMC 647 * 648 * This routine is called when 649 * the KMC generates an unsolicited interrupt (VEC4 == 1) 650 * 651 * These interrupts are used by the KMC to notify dkit_kmc.c 652 * of events such as output buffer completions 653 * csr6 & csr7 point to dkkstat 654 */ 655 dkkint() 656 { 657 register struct dkchan *dkp; 658 register struct dkkin *sp; 659 register chan; 660 struct mpacket *mbp ; 661 int (*endfcn)(); 662 663 M_ON(Mkint) ; 664 665 chan = csr0 ; /* temp for cc -O bug */ 666 if((chan & 01) == 1) /* 1 or 3 -> ignore */ 667 return; 668 sp = stat7 ; /* next response to be processed */ 669 while (csr6 != csr7) { 670 if (kseqchk) 671 if ((((sp->k_chan >> 8)&0377) != kseq) || 672 (((sp->k_type >> 8)&0377) != kseq)) { 673 log(LOG_ERR, "dkkint: kseq %x chan %d type %x\n", 674 kseq, sp->k_chan, sp->k_type) ; 675 goto reset ; 676 } 677 kseq = (kseq + 1) & 0377 ; 678 sp->k_addr = pseq ; 679 pseq++ ; 680 chan = sp->k_chan & 0377 ; /* mask off seq. # */ 681 dkp = &dkit[chan]; 682 if (chan > dkdebug) { 683 log(LOG_ERR, " dkkint: head %d tail %d", csr6, csr7) ; 684 log(LOG_ERR, " type %x chan %d len %d mode %x ctl %x\n", sp->k_type&0377, sp->k_chan&0377, sp->k_len, sp->k_mode, sp->k_ctl) ; 685 } 686 switch(sp->k_type & 0377) { 687 case KS_CNTL: 688 if (dkp->dk_supfcn) 689 (*dkp->dk_supfcn)(chan, sp->k_ctl) ; 690 break ; 691 case KS_EOI: 692 break ; 693 case KS_SEND: 694 mbp = dkp->dk_obuf ; 695 if (mbp == NULL) { 696 if (dkp->dk_state & (DK_RESET|DK_LINGR)) 697 break; /* flushall was already called */ 698 log(LOG_ERR, "dkkint: xbufout chan %d state %x\n", chan, dkp->dk_state) ; 699 log(LOG_ERR, "head %d tail %d", csr6, csr7) ; 700 log(LOG_ERR, " type %x len %d mode %x ctl %x\n", 701 sp->k_type&0377, sp->k_len, sp->k_mode, sp->k_ctl) ; 702 break ; 703 } 704 dkp->dk_state &= ~DK_BUSY; 705 dkp->dk_obuf = NULL ; 706 if (endfcn = mbp->mp_endfcn) { 707 mbp->mp_endfcn = NULL; 708 (endfcn)(mbp->mp_endparm, chan) ; 709 } 710 m_free(dtom(mbp)) ; 711 if (dkp->dk_uba.ifu_xtofree) { 712 m_freem(dkp->dk_uba.ifu_xtofree); 713 dkp->dk_uba.ifu_xtofree = 0; 714 } 715 if (dkp->dk_outq.ifq_head) 716 dkstart(dkp) ; 717 break; 718 case KS_RDB: 719 if (((dkp->dk_state & DK_RCV) == 0) && dkp->dk_endfcn) { 720 log(LOG_ERR, "dkkint: rbufin chan %d state %x\n", chan, dkp->dk_state) ; 721 log(LOG_ERR, " head %d tail %d\n", csr6, csr7) ; 722 log(LOG_ERR, " type %x len %d mode %x ctl %x\n", 723 sp->k_type&0377, sp->k_len, sp->k_mode, sp->k_ctl) ; 724 725 if (sp->k_ctl) 726 break ; 727 else { 728 stat7 = sp ; /* save it for dump */ 729 csr0 = 3 ; /* stop KMC */ 730 panic("") ; /* KMC probably wrote 731 into a mbuf we don't own */ 732 } 733 } 734 dkp->dk_state &= ~DK_RCV ; 735 if (dkp->dk_ubmbase) { 736 ubarelse(ui->ui_ubanum, &dkp->dk_ubmbase); 737 dkp->dk_ubmbase = NULL; 738 } 739 if (endfcn = dkp->dk_endfcn) { 740 dkp->dk_endfcn = NULL; 741 (endfcn)(dkp->dk_endparm, chan, sp->k_len, sp->k_mode, sp->k_ctl) ; 742 } 743 break; 744 case KS_ERR: 745 log(LOG_ERR, "dkkint: err : chan %d, code %x\nchead: %d, ctail: %d, rhead: %d, rtail: %d\n", 746 chan, sp->k_len, csr4, csr5, csr6, csr7); 747 748 /* if error is duplicate send, only close that chan, */ 749 /* not the whole interface */ 750 751 if (sp->k_len == E_DUP) { 752 dup_count++; 753 if (dkp->dk_state & DK_OPEN) { 754 dk_reset(chan); 755 } 756 break; 757 } 758 reset: 759 (void) dk_close(0) ; 760 return ; 761 default: 762 log(LOG_ERR, "dkkint: chan %d, type %x, len %d, ctl %x, mode %x\n", 763 chan, sp->k_type&0377, sp->k_len, sp->k_ctl, sp->k_mode); 764 goto reset ; 765 } /* end switch */ 766 767 if (csr7 == dkk_nstat-1) { 768 csr7 = 0 ; 769 sp = &dkkstat[0] ; 770 } else { 771 csr7++ ; 772 sp++ ; 773 } 774 775 } /* end while */ 776 stat7 = sp ; 777 M_OFF(Mkint) ; 778 } 779 780 /* 781 * Start (Restart) transmission on the given line 782 */ 783 dkstart(dkp) 784 register struct dkchan *dkp; 785 { 786 register struct mpacket *mbp; 787 register struct mbuf *m; 788 int len; 789 790 /* 791 * If it is currently active, just return 792 */ 793 if (dkp->dk_state&DK_BUSY) 794 return; 795 796 IF_DEQUEUE(&dkp->dk_outq, m); 797 if (!m) 798 return; 799 mbp = mtod(m, struct mpacket *); 800 801 dkp->dk_state |= DK_BUSY ; 802 dkp->dk_obuf = mbp ; 803 len = if_wubaput(&dkp->dk_uba, m->m_next); 804 dkcmd(KC_SEND, dkp-dkit, (caddr_t) UBAI_ADDR(dkp->dk_uba.ifu_w.ifrw_info), 805 (unsigned) len, mbp->mp_eob ? SBOT : SBOTM, mbp->mp_ctl) ; 806 } 807 808 /* 809 * Put command in dkkcmdbuf which is pointed by csr4~5 810 */ 811 dkcmd(type, chan, addr, len, mode, ctl) 812 int type, chan; 813 caddr_t addr ; 814 unsigned len ; 815 { 816 register struct dkkin *sp; 817 register s; 818 register next; 819 register loop; 820 struct timeval tv1, tv2; 821 822 M_ON(Mcmd) ; 823 s = csr0 ; 824 if ((s & 3) != 2) 825 return; 826 827 s = splimp(); 828 next = (csr4+1)%dkk_ncmd; 829 loop = 0; 830 while (csr5 == next) { 831 /* give it a chance to empty the buffer */ 832 if (loop++>10000000) { 833 log(LOG_ERR, "KMC DIED, restart\n"); 834 dk_close(0); 835 splx(s); 836 return; 837 } 838 log(LOG_ERR, "KMC cmd overrun for %ld\n", loop); 839 } 840 841 sp = cmd4 ; 842 sp->k_type = type | ((pseq&0177)<<9) ; 843 sp->k_chan = chan | ((kseq&0377)<<8) ; 844 sp->k_addr = ((int)addr << 16) + ((int)addr >> 16) ; 845 sp->k_len = len ; 846 sp->k_mode = mode ; 847 sp->k_ctl = ctl ; 848 pseq++ ; 849 850 csr4 = next; 851 cmd4 = &dkkcmdbuf[next]; 852 853 if (chan > dkdebug) { 854 log(LOG_ERR, " dkcmd: head %d, tail %d", csr4, csr5); 855 log(LOG_ERR, " type %x, chan %d, addr %x, len %d", 856 type, chan, addr, len); 857 log(LOG_ERR, " mode %x, ctl %x\n", mode, ctl); 858 } 859 splx(s) ; 860 M_OFF(Mcmd) ; 861 } 862 863 #endif 864