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