1: /*	%W% (Berkeley) %G% */
   2: 
   3: 
   4: /************************************************************************\
   5: 
   6:      ________________________________________________________
   7:     /                                                        \
   8:    |          AAA          CCCCCCCCCCCCCC    CCCCCCCCCCCCCC   |
   9:    |         AAAAA        CCCCCCCCCCCCCCCC  CCCCCCCCCCCCCCCC  |
  10:    |        AAAAAAA       CCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCC |
  11:    |       AAAA AAAA      CCCC              CCCC              |
  12:    |      AAAA   AAAA     CCCC              CCCC              |
  13:    |     AAAA     AAAA    CCCC              CCCC              |
  14:    |    AAAA       AAAA   CCCC              CCCC              |
  15:    |   AAAA  AAAAAAAAAAA  CCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCC |
  16:    |  AAAA    AAAAAAAAAAA CCCCCCCCCCCCCCCC  CCCCCCCCCCCCCCCC  |
  17:    | AAAA      AAAAAAAAA   CCCCCCCCCCCCCC    CCCCCCCCCCCCCC   |
  18:     \________________________________________________________/
  19: 
  20: 	Copyright (c) 1984 by Advanced Computer Communications
  21: 	720 Santa Barbara Street, Santa Barbara, California  93101
  22: 	(805) 963-9431
  23: 
  24: 	This software may be duplicated and used on systems
  25: 	which are licensed to run U.C. Berkeley versions of
  26: 	the UNIX operating system.  Any duplication of any
  27: 	part of this software must include a copy of ACC's
  28: 	copyright notice.
  29: 
  30: 
  31: File:
  32: 		if_hdh.c
  33: 
  34: Author:
  35: 		Art Berggreen
  36: 
  37: Project:
  38: 		4.2BSD HDH
  39: 
  40: Function:
  41: 		Device specific driver for IF-11/HDH under 4.2BSD
  42:     		networking code.
  43: 
  44: Revision History:
  45: 		Converted to 4.3, updated, UCB.
  46: 		31-Aug-1984: V1.0 - First Implementation. A.B.
  47: 		 6-Nov-1984: V1.1 - Supress extra "LINE DOWN" msgs. A.B.
  48: 		13-Jan-1984: V1.2 - Add conditionals for TWG. A.B.
  49: 
  50: \************************************************************************/
  51: 
  52: 
  53: 
  54: 
  55: /* $Header$ */
  56: 
  57: #include "hdh.h"
  58: #ifdef NHDH > 0
  59: 
  60: /*
  61:  *
  62:  * ACC IF-11/HDH interface
  63:  *
  64:  */
  65: 
  66: #include "param.h"
  67: #include "systm.h"
  68: #include "mbuf.h"
  69: #include "buf.h"
  70: #include "protosw.h"
  71: #include "socket.h"
  72: #include "vmmac.h"
  73: 
  74: #include "../machine/pte.h"
  75: 
  76: #include "../net/if.h"
  77: #include "../netimp/if_imp.h"
  78: 
  79: #include "../vax/cpu.h"
  80: #include "../vax/mtpr.h"
  81: #include "../vaxuba/ubareg.h"
  82: #include "../vaxuba/ubavar.h"
  83: 
  84: #include "if_hdhreg.h"
  85: #include "if_uba.h"
  86: 
  87: int     hdhprobe(), hdhattach(), hdhintr();
  88: struct  uba_device *hdhinfo[NHDH];
  89: u_short hdhstd[] = { 0 };
  90: struct  uba_driver hdhdriver =
  91:     { hdhprobe, 0, hdhattach, 0, hdhstd, "hdh", hdhinfo };
  92: 
  93: #define HDHUNIT(x)  minor(x)
  94: 
  95: int hdhinit(), hdhoutput(), hdhreset();
  96: 
  97: /*
  98:  * "Lower half" of IMP interface driver.
  99:  *
 100:  * Each IMP interface is handled by a common module which handles
 101:  * the IMP-host protocol and a hardware driver which manages the
 102:  * hardware specific details of talking with the IMP.
 103:  *
 104:  * The hardware portion of the IMP driver handles DMA and related
 105:  * management of UNIBUS resources.  The IMP protocol module interprets
 106:  * contents of these messages and "controls" the actions of the
 107:  * hardware module during IMP resets, but not, for instance, during
 108:  * UNIBUS resets.
 109:  *
 110:  * The two modules are coupled at "attach time", and ever after,
 111:  * through the imp interface structure.  Higher level protocols,
 112:  * e.g. IP, interact with the IMP driver, rather than the HDH.
 113:  */
 114: 
 115: #define NHDHCH  2       /* no. of FDX channels for HDH */
 116: #define SUPR    0       /* supervisor channel */
 117: #define DATA    1       /* data channel */
 118: #define HDHSUPR 0       /* supervisor read */
 119: #define HDHSUPW 1       /* supervisor write */
 120: #define HDHDATR 2       /* data read */
 121: #define HDHDATW 3       /* data write */
 122: 
 123: #define HDH_UP      2   /* HDH protocol is up */
 124: #define HDH_STARTED 1   /* HDH has been initialized */
 125: 
 126: #define HCBUSY  1       /* HDH HDX channel busy flag */
 127: 
 128: /*
 129: /* The IF-11/HDH has four independent dath flow channels between the
 130: /* front-end and the host.  Two are used for reading and writing
 131: /* control messages and two are used for data flow.  Each IF-11/HDH
 132: /* has a device dependent data structure (hdh_softc) which contains
 133: /* an array of four channel dependent structures (hdh_chan) to maintain
 134: /* the context of each channel.  Channel structures can be linked into
 135: /* a queue of I/O requests pending for the hardware interface.
 136: /* UNIBUS mapping resources are allocated for each channel pair.
 137: */
 138: 
 139: struct  hdh_chan {      /* HDH HDX channel structure */
 140:     struct hdh_chan *hc_next;   /* link for Start I/O queuing */
 141:     char        hc_chan;    /* HDX chan number */
 142:     char        hc_adx;     /* extended UNIBUS address bits */
 143:     short       hc_addr;    /* lower UNIBUS address bits */
 144:     short       hc_cnt;     /* byte count */
 145:     char        hc_func;    /* UMC I/O function */
 146:     char        hc_sbfc;    /* UMC I/O subfunction */
 147:     short       hc_flags;   /* status flags */
 148: };
 149: 
 150: struct  hdh_sioq {      /* Start I/O queue head structure */
 151:     struct hdh_chan *sioq_head; /* pointer to queue head */
 152:     struct hdh_chan *sioq_tail; /* pointer to queue tail */
 153: };
 154: 
 155: struct  hdh_softc {     /* HDH device dependent structure */
 156:     struct imp_softc *hdh_imp;  /* pointer to IMP's imp_softc struct */
 157:     struct ifuba    hdh_ifuba[NHDHCH]; /* UNIBUS resources */
 158:     struct hdh_chan hdh_chan[2*NHDHCH]; /* HDX HDH channels */
 159:     struct hdh_sioq hdh_sioq;   /* start i/o queue */
 160:     short       hdh_flags;  /* various status conditions */
 161: } hdh_softc[NHDH];
 162: 
 163: 
 164: /*
 165:  * Normally, code goes here to cause the device to interrupt to determine its
 166:  * interrupt vector.  However, since the UMC must be told its vector in order
 167:  * to interrupt, we allocate and return an unused vector and initialize the
 168:  * UMC.
 169:  */
 170: hdhprobe(reg)
 171: caddr_t reg;
 172: {
 173:     register int br, cvec;
 174:     struct hdhregs *addr = (struct hdhregs *)reg;
 175: #ifdef lint
 176:     br = 0; cvec = br; br = cvec;
 177:     hdhintr(0);
 178: #endif
 179: 
 180:     br = 0x15;          /* priority 21 (5 on UNIBUS) */
 181: 
 182: #ifdef HDHDEBUG
 183:     cvec = 0270;            /* use constant for now ... */
 184: #else
 185: 
 186: #ifdef VAXVMS               /* if VMS */
 187:     cvec = 0270;            /*   we can't allocate vectors */
 188: #else
 189:     cvec = (uba_hd[numuba].uh_lastiv -= 4);  /* available vector */
 190: #endif VAXVMS
 191: 
 192: #endif HDHDEBUG
 193: 
 194:     addr->ioini = (char) 0;     /* init UMC regs */
 195:     addr->staack = (char) 0;    /*   pass vector */
 196:     addr->ionmi = (char) 0;     /*     and kick UMC */
 197:     addr->iochn = (char) (cvec >> 2);
 198:     addr->csr = (short) HDH_RST;
 199:     addr->csr = (short) (HDH_IEN|HDH_DMA|HDH_WRT); /* set enables */
 200:     DELAY(5000);            /* give the UMC some time */
 201:     return(1);
 202: }
 203: 
 204: /*
 205:  * Call the IMP module to allow it to set up its internal
 206:  * state, then tie the two modules together by setting up
 207:  * the back pointers to common data structures.
 208:  */
 209: hdhattach(ui)
 210:     register struct uba_device *ui;
 211: {
 212:     register struct hdh_softc *sc = &hdh_softc[ui->ui_unit];
 213:     register struct impcb *ip;
 214: 
 215:     if ((sc->hdh_imp = impattach(ui->ui_driver->ud_dname, ui->ui_unit,
 216:         hdhreset)) == 0)
 217:         return;
 218:     ip = &sc->hdh_imp->imp_cb;
 219:     ip->ic_init = hdhinit;
 220:     ip->ic_output = hdhoutput;
 221:     sc->hdh_ifuba[ui->ui_unit].ifu_flags = UBA_CANTWAIT;
 222: }
 223: 
 224: /*
 225:  * Reset interface after UNIBUS reset.
 226:  */
 227: hdhreset(unit, uban)
 228: int unit, uban;
 229: {
 230:     register struct uba_device *ui = hdhinfo[unit];
 231:     register struct hdh_softc *sc = &hdh_softc[unit];
 232: 
 233: #ifdef HDHDEBUG
 234:     printf("HDH RESET\n");
 235: #endif HDHDEBUG
 236: 
 237:     if ((unit >= NHDH) || (ui == 0) || (ui->ui_alive == 0)
 238:         || (ui->ui_ubanum != uban))
 239:         return;
 240:     printf(" hdh%d", unit);
 241:     sc->hdh_imp->imp_if.if_flags &= ~IFF_RUNNING;
 242:     sc->hdh_flags = 0;
 243:     (*sc->hdh_imp->imp_if.if_init)(sc->hdh_imp->imp_if.if_unit);
 244: }
 245: 
 246: /*
 247:  * Initialize the imp interface.
 248:  */
 249: 
 250: static char init_blk[] =
 251:     {
 252:     HDHINIT,        /* SYSINIT opcode			*/
 253:     HDHRQUP & 0xff,     /* control code (LSB)			*/
 254:     (HDHRQUP>>8) & 0xff,    /* control code (MSB)			*/
 255:     10,         /* command extension len		*/
 256:     0,          /* loopback mode (off)			*/
 257:     3,          /* our address (3=DTE)			*/
 258:     1,          /* their address (1=DCE)		*/
 259:     3,          /* frame ack t1 timeout			*/
 260:     3,          /* poll ack timeout			*/
 261:     30,         /* adm wait timeout			*/
 262:     3,          /* rej wait timeout			*/
 263:     10,         /* max retries				*/
 264:     3,          /* watchdog timeout			*/
 265:     0xaa            /* baud rate (0xaa=38.4KB)		*/
 266:                 /*   (output on RS-232 pin 24,		*/
 267:                 /*    send/receive timing is always	*/
 268:                 /*    taken from pins 15/17)		*/
 269:     };
 270: 
 271: hdhinit(unit)
 272: int unit;
 273: {
 274:     register struct hdh_softc *sc;
 275:     register struct uba_device *ui;
 276:     int i;
 277: 
 278: #ifdef HDHDEBUG
 279:     printf("HDH INIT\n");
 280: #endif HDHDEBUG
 281: 
 282:     if (unit >= NHDH || (ui = hdhinfo[unit]) == NULL
 283:         || ui->ui_alive == 0) {
 284:         printf("hdh%d: not alive\n", unit);
 285:         return(0);
 286:     }
 287:     sc = &hdh_softc[unit];
 288: 
 289:     if (sc->hdh_flags & HDH_STARTED)
 290:         return(1);
 291: 
 292:     /*
 293: 	 * Alloc uba resources
 294: 	 */
 295:     if ((sc->hdh_imp->imp_if.if_flags & IFF_RUNNING) == 0)
 296:         for(i=0;i<NHDHCH;i++) {
 297:         if (if_ubainit(&sc->hdh_ifuba[i], ui->ui_ubanum, 0,
 298:             (int)btoc(IMP_RCVBUF)) == 0) {
 299:             printf("hdh%d: cannot get chan %d uba resources\n",
 300:                 unit, i);
 301:             ui->ui_alive = 0;
 302:             return(0);
 303:         }
 304:     }
 305: 
 306:     sc->hdh_imp->imp_if.if_flags |= IFF_RUNNING;
 307:     sc->hdh_flags = HDH_STARTED;
 308: 
 309:     /*
 310: 	 * hang a supervisor read (for line status)
 311: 	 */
 312:     hdh_iorq(unit, HDHSUPR, IMP_RCVBUF, HDHRDB);
 313: 
 314:     /*
 315: 	 * hang a data read
 316: 	 */
 317:     hdh_iorq(unit, HDHDATR, IMP_RCVBUF, HDHRDB+HDHSTR);
 318: 
 319:     /*
 320: 	 * bring up line to IMP
 321: 	 */
 322: 
 323:     snd_supr(unit, init_blk, sizeof(init_blk));
 324: 
 325:     return(1);
 326: }
 327: 
 328: /*
 329:  * Start an output operation on an mbuf.
 330:  */
 331: hdhoutput(unit, m)
 332:     int unit;
 333:     struct mbuf *m;
 334: {
 335:     register struct hdh_softc *sc = &hdh_softc[unit];
 336:         int len;
 337: 
 338:     /*
 339: 	 * If output isn't active, attempt to
 340: 	 * start sending a new packet.
 341: 	 */
 342: 
 343:     if (sc->hdh_imp->imp_cb.ic_oactive) {
 344:         printf("hdh%d: start on active unit\n", unit);
 345:         return;
 346:     }
 347: 
 348:     if ((sc->hdh_flags & HDH_UP) == 0) {
 349:         /* Link not up, can't xmit */
 350:         return;
 351:     }
 352: 
 353:     len = if_wubaput(&sc->hdh_ifuba[DATA], m);  /* copy data to mapped mem */
 354:     sc->hdh_imp->imp_cb.ic_oactive = 1;
 355: 
 356:     hdh_iorq(unit, HDHDATW, len, HDHWRT+HDHEOS);
 357: }
 358: 
 359: /*
 360:  * Start i/o operation on a UMC logical channel
 361:  */
 362: hdh_iorq(unit, lcn, len, func)
 363: int unit, lcn, len, func;
 364: {
 365:     register struct hdh_softc *sc = &hdh_softc[unit];
 366:     register struct hdh_chan *hc = &sc->hdh_chan[lcn];
 367:     register int info, s;
 368: 
 369:     /*
 370: 	 * If channel is busy (shouldn't be), drop.
 371: 	 */
 372:     if  (hc->hc_flags & HCBUSY) {
 373:         printf("hdh%d: channel busy lcn=%d\n", unit, lcn);
 374:         return;
 375:     }
 376: 
 377:     /* get appropriate UNIBUS mapping info */
 378: 
 379:     if (lcn & 1)        /* read or write? */
 380:         info = sc->hdh_ifuba[lcn>>1].ifu_w.ifrw_info;
 381:     else
 382:         info = sc->hdh_ifuba[lcn>>1].ifu_r.ifrw_info;
 383: 
 384:     /* set channel info */
 385: 
 386:     hc->hc_flags |= HCBUSY;
 387:     hc->hc_chan = lcn;
 388:     hc->hc_adx = (char)((info & 0x30000) >> 12);
 389:     hc->hc_addr = (unsigned short)(info & 0xffff);
 390:     hc->hc_cnt = len;
 391:     hc->hc_func = (char)func;
 392:     hc->hc_sbfc = 0;
 393: 
 394:     s = splimp();
 395:     /*
 396: 	 * If UMC comm regs busy, queue start i/o for later.
 397: 	 */
 398:     if (sc->hdh_sioq.sioq_head) {
 399:         (sc->hdh_sioq.sioq_tail)->hc_next = hc;
 400:         sc->hdh_sioq.sioq_tail = hc;
 401:         hc->hc_next = 0;
 402:         splx(s);
 403:         return;
 404:     }
 405: 
 406:     /* start i/o on channel now */
 407: 
 408:     sc->hdh_sioq.sioq_head = hc;
 409:     sc->hdh_sioq.sioq_tail = hc;
 410:     hc->hc_next = 0;
 411:     start_chn(unit);
 412:     splx(s);
 413: }
 414: 
 415: start_chn(unit)
 416: int unit;
 417: {
 418:     register struct hdh_softc *sc = &hdh_softc[unit];
 419:     register struct hdh_chan *hc = sc->hdh_sioq.sioq_head;
 420:     register struct hdhregs *addr = (struct hdhregs *)hdhinfo[unit]->ui_addr;
 421: 
 422:     /*
 423: 	 * Set up comm regs.
 424: 	 */
 425:     addr->iochn = hc->hc_chan;
 426:     addr->ioadx = hc->hc_adx;
 427:     addr->ioadl = hc->hc_addr;
 428:     addr->iocnt = hc->hc_cnt;
 429:     addr->iofcn = hc->hc_func;
 430:     addr->iosbf = hc->hc_sbfc;
 431:     addr->ioini = 1;
 432: 
 433:     /* signal UMC if necessary */
 434: 
 435:     if (!(addr->ionmi)) {
 436:         addr->ionmi = 1;
 437:         addr->csr = HDH_DMA|HDH_WRT|HDH_IEN|HDH_NMI;
 438:     }
 439: }
 440: 
 441: /*
 442:  * IF-11/HDH interrupt handler
 443:  */
 444: hdhintr(unit)
 445: int unit;
 446: {
 447:     register struct hdh_softc *sc = &hdh_softc[unit];
 448:     register struct hdh_chan *hc;
 449:     register struct hdhregs *addr = (struct hdhregs *)hdhinfo[unit]->ui_addr;
 450:     int lcn, type, cc, cnt;
 451: 
 452:     /*
 453: 	 * Check for hardware errors.
 454: 	 */
 455:     if (addr->csr & HDH_UER) {
 456:         printf("hdh%d: hard error csr=%b\n", unit, addr->csr, HDH_BITS);
 457:         addr->csr = 0;      /* disable i/f */
 458:         return;
 459:     }
 460:     /*
 461: 	 * Get logical channel info.
 462: 	 */
 463:     if ((lcn = addr->stachn) >= (NHDHCH*2)) {
 464:         printf("hdh%d: unknown channel lcn=%d\n", unit, lcn);
 465:         return;
 466:     }
 467: 
 468:     hc = &sc->hdh_chan[lcn];
 469: 
 470:     type = addr->statyp;
 471:     cc = addr->stacc;
 472:     cnt = hc->hc_cnt - addr->stacnt;
 473: 
 474:     /* Figure out what kind of interrupt it was */
 475: 
 476:     switch(type) {
 477: 
 478:     case HDHSACK:       /* start i/o accepted */
 479:         if (hc != sc->hdh_sioq.sioq_head) {
 480:             printf("hdh%d: STARTIO error lcn=%d hc=%x sq=%x\n",
 481:                 unit, lcn, hc, sc->hdh_sioq.sioq_head);
 482:             return;
 483:         }
 484: 
 485:         /* try to start any queued i/o request */
 486: 
 487:         if (sc->hdh_sioq.sioq_head = sc->hdh_sioq.sioq_head->hc_next) {
 488:             start_chn(unit);
 489:         }
 490:         break;
 491: 
 492:     case HDHDONE:       /* i/o completion */
 493:         switch (cc) {
 494: 
 495:         case HDHIOCABT:
 496:             printf("hdh%d: I/O abort ", unit);
 497:             goto daterr;
 498: 
 499:         case HDHIOCERR:
 500:             printf("hdh%d: program error ", unit);
 501:             goto daterr;
 502: 
 503:         case HDHIOCOVR:
 504:             printf("hdh%d: overrun error ", unit);
 505:             goto daterr;
 506: 
 507:         case HDHIOCUBE:
 508:             printf("hdh%d: NXM timeout or UB parity error ", unit);
 509: 
 510:         daterr:
 511:             printf("lcn=%d func=%x\n", lcn, hc->hc_func);
 512:             if (hc->hc_func & HDHRDB)
 513:                 sc->hdh_imp->imp_if.if_ierrors++;
 514:             else
 515:                 sc->hdh_imp->imp_if.if_oerrors++;
 516:         }
 517: 
 518:         hc->hc_flags &= ~HCBUSY;
 519: 
 520:         /* was it supervisor or data traffic? */
 521: 
 522:         if (lcn > HDHSUPW)
 523:             hdh_data(unit, lcn, cc, cnt);
 524:         else
 525:             hdh_supr(unit, lcn, cc);
 526: 
 527:     }
 528: 
 529:     /*
 530: 	 * Ack the interrupt
 531: 	 */
 532:     addr->staack = 1;
 533:     if (!(addr->ionmi)) {
 534:         addr->ionmi = 1;
 535:         addr->csr = HDH_DMA|HDH_WRT|HDH_IEN|HDH_NMI;
 536:     }
 537: }
 538: 
 539: /*
 540:  * data channel interrupt completion handler
 541:  */
 542: hdh_data(unit, lcn, cc, rcnt)
 543: int unit, lcn, cc, rcnt;
 544: {
 545:     register struct hdh_softc *sc = &hdh_softc[unit];
 546:     register struct hdh_chan *hc = &sc->hdh_chan[lcn];
 547:     register struct mbuf *m;
 548: 
 549: 
 550:     /* was it read or write? */
 551: 
 552:     if (hc->hc_func & HDHRDB) {
 553:         if (cc == HDHIOCOK) {
 554:             /*
 555: 			 * Queue good packet for input
 556: 			 */
 557:             sc->hdh_imp->imp_if.if_ipackets++;
 558:             m = if_rubaget(&sc->hdh_ifuba[lcn>>1], rcnt, 0,
 559:                 &sc->hdh_imp->imp_if);
 560:             impinput(unit, m);
 561:         }
 562: 
 563:         /* hang a new data read */
 564: 
 565:         hdh_iorq(unit, lcn, IMP_RCVBUF, HDHRDB+HDHSTR);
 566: 
 567:     } else {
 568:         /*
 569: 		 * fire up next output
 570: 		 */
 571:         sc->hdh_imp->imp_if.if_opackets++;
 572:         sc->hdh_imp->imp_cb.ic_oactive = 0;
 573:         impstart(sc->hdh_imp->imp_if.if_unit);
 574:     }
 575: }
 576: 
 577: /*
 578:  * supervisor channel interrupt completion handler
 579:  */
 580: hdh_supr(unit, lcn, cc)
 581: int unit, lcn, cc;
 582: {
 583:     register struct hdh_softc *sc = &hdh_softc[unit];
 584:     register struct hdh_chan *hc = &sc->hdh_chan[lcn];
 585:     short *p;
 586: 
 587: 
 588:     /* was it read or write? */
 589: 
 590:     if (hc->hc_func & HDHRDB) {
 591:         if (cc == HDHIOCOK) {
 592:             p = (short *)(sc->hdh_ifuba[lcn>>1].ifu_r.ifrw_addr);
 593: 
 594:             /* figure out what kind of supervisor message */
 595: 
 596:             switch (*p) {
 597: 
 598:             case HDHIACK:
 599:             case HDHLNACK:
 600:                 break;
 601: 
 602:             case HDHLNUP:
 603:                 printf("hdh%d: LINE UP\n", unit);
 604:                 sc->hdh_flags |= HDH_UP;
 605:                 impstart(sc->hdh_imp->imp_if.if_unit);
 606:                 break;
 607: 
 608:             case HDHLNDN:
 609:                 if (sc->hdh_flags & HDH_UP)
 610:                     printf("hdh%d: LINE DOWN\n", unit);
 611:                 sc->hdh_flags &= ~HDH_UP;
 612:                 break;
 613: 
 614:             case HDHLOOP:
 615:                 break;
 616: 
 617:             case HDHSQERR:
 618:                 printf("hdh%d: HOST SEQUENCE ERROR\n", unit);
 619:                 break;
 620: 
 621:             case HDHSQRCV:
 622:                 printf("hdh%d: IMP SEQUENCE ERROR\n", unit);
 623:                 break;
 624: 
 625:             case HDHDTERR:
 626:                 printf("hdh%d: HOST DATA ERROR\n", unit);
 627:                 break;
 628: 
 629:             case HDHTIMO:
 630:                 printf("hdh%d: TIMEOUT\n", unit);
 631:                 break;
 632: 
 633:             default:
 634:                 printf("hdh%d: supervisor error, code=%x\n",
 635:                     unit, *p);
 636:             }
 637:         }
 638: 
 639:         /* hang a new supr read */
 640: 
 641:         hdh_iorq(unit, HDHSUPR, IMP_RCVBUF, HDHRDB+HDHSTR);
 642:     }
 643: }
 644: 
 645: snd_supr(unit, msg, len)
 646: int unit, len;
 647: char *msg;
 648: {
 649:     register struct hdh_softc *sc = &hdh_softc[unit];
 650:     register struct mbuf *m;
 651:     register char *p;
 652:     register int cnt;
 653: 
 654:     if ((m = m_get(M_DONTWAIT, MT_DATA)) == NULL) {
 655:         printf("hdh%d: cannot get supervisor cmnd buffer\n", unit);
 656:             return;
 657:     }
 658: 
 659:     cnt = len;
 660:     m->m_len = len;
 661:     p = mtod(m, char *);
 662: 
 663:     while(cnt--) *p++ = *msg++;
 664: 
 665:     cnt = if_wubaput(&sc->hdh_ifuba[SUPR], m);
 666: 
 667:     hdh_iorq(unit, HDHSUPW, cnt, HDHWRT+HDHEOS);
 668: }
 669: #endif NHDH

Defined functions

hdh_data defined in line 542; used 1 times
hdh_iorq defined in line 362; used 6 times
hdh_supr defined in line 580; used 1 times
hdhattach defined in line 209; used 2 times
hdhinit defined in line 271; used 2 times
hdhintr defined in line 444; used 2 times
hdhoutput defined in line 331; used 2 times
hdhprobe defined in line 170; used 2 times
hdhreset defined in line 227; used 2 times
snd_supr defined in line 645; used 1 times
start_chn defined in line 415; used 2 times

Defined variables

hdh_softc defined in line 161; used 10 times
hdhdriver defined in line 90; never used
hdhinfo defined in line 88; used 5 times
hdhstd defined in line 89; used 1 times
  • in line 91
init_blk defined in line 250; used 2 times
  • in line 323(2)

Defined struct's

hdh_chan defined in line 139; used 18 times
hdh_sioq defined in line 150; used 2 times
  • in line 159(2)
hdh_softc defined in line 155; used 20 times

Defined macros

DATA defined in line 117; used 1 times
HCBUSY defined in line 126; used 3 times
HDHDATR defined in line 120; used 1 times
HDHDATW defined in line 121; used 1 times
HDHSUPR defined in line 118; used 2 times
HDHSUPW defined in line 119; used 2 times
HDHUNIT defined in line 93; never used
HDH_STARTED defined in line 124; used 2 times
HDH_UP defined in line 123; used 4 times
NHDHCH defined in line 115; used 4 times
SUPR defined in line 116; used 1 times
Last modified: 1988-02-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 985
Valid CSS Valid XHTML 1.0 Strict