kernel: Replace all usage of MALLOC()/FREE() with kmalloc()/kfree().
[dragonfly.git] / sys / dev / misc / musycc / musycc.c
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7  * ----------------------------------------------------------------------------
8  *
9  * $FreeBSD: src/sys/dev/musycc/musycc.c,v 1.17.2.3 2001/03/13 22:05:36 phk Exp $
10  *
11  *
12  *
13  * Card state machine:
14  * -------------------
15  *
16  * This is the state engine which drives the card "as such" which in reality
17  * means the MUSYCC chip.
18  *
19  *  State       Description
20  *
21  *  IDLE        The card is in this state when no channels are configured.
22  *              This is the state we leave the card in after _attach()
23  *
24  *  INIT        The card is being initialized
25  *
26  *  RUNNING     The card is running
27  *
28  *  FAULT       The card is hosed and being reset
29  *
30  *      ------------------
31  *     /                  \
32  *    v                    |
33  *  IDLE ---> INIT ---> RUNNING
34  *                       ^   |
35  *                       |   |
36  *                       |   v
37  *                       FAULT
38  *
39  */
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/conf.h>
44 #include <sys/kernel.h>
45 #include <sys/sysctl.h>
46 #include <sys/malloc.h>
47 #include <sys/bus.h>
48 #include <sys/mbuf.h>
49 #include <sys/queue.h>
50 #include <sys/rman.h>
51
52 #include <machine/clock.h>
53
54 #include <bus/pci/pcireg.h>
55 #include <bus/pci/pcivar.h>
56
57 #include "pci_if.h"
58
59 #include <netgraph/ng_message.h>
60 #include <netgraph/netgraph.h>  
61
62 #include <vm/vm.h>
63 #include <vm/pmap.h>
64
65 static MALLOC_DEFINE(M_MUSYCC, "musycc", "MUSYCC related");
66
67 static int maxlatency = 250;
68 SYSCTL_INT(_debug, OID_AUTO, musycc_maxlatency, CTLFLAG_RW, &maxlatency, 0,
69         "The number of milliseconds a packet is allowed to spend in the output queue.  "
70         "If the output queue is longer than this number of milliseconds when the packet "
71         "arrives for output, the packet will be dropped."
72 );
73
74 static int debug = 0;
75 SYSCTL_INT(_debug, OID_AUTO, musycc_debug, CTLFLAG_RW, &debug, 0, "");
76
77 struct softc;
78 static void init_8370(struct softc *sc);
79 static  u_int32_t parse_ts(const char *s, int *nbit);
80
81 /*
82  * Device driver initialization stuff
83  */
84
85 static devclass_t musycc_devclass;
86
87 /* XXX: Notice, these babies must be aligned to 2k boundaries [5-7] */
88 struct groupr {
89         u_int32_t       thp[32];   /* Transmit Head Pointer [5-29]           */
90         u_int32_t       tmp[32];   /* Transmit Message Pointer [5-30]        */
91         u_int32_t       rhp[32];   /* Receive Head Pointer [5-29]            */
92         u_int32_t       rmp[32];   /* Receive Message Pointer [5-30]         */
93         u_int8_t        ttsm[128]; /* Time Slot Map [5-22]                   */
94         u_int8_t        tscm[256]; /* Subchannel Map [5-24]                  */
95         u_int32_t       tcct[32];  /* Channel Configuration [5-26]           */
96         u_int8_t        rtsm[128]; /* Time Slot Map [5-22]                   */
97         u_int8_t        rscm[256]; /* Subchannel Map [5-24]                  */
98         u_int32_t       rcct[32];  /* Channel Configuration [5-26]           */
99         u_int32_t       __glcd;    /* Global Configuration Descriptor [5-10] */
100         u_int32_t       __iqp;     /* Interrupt Queue Pointer [5-36]         */
101         u_int32_t       __iql;     /* Interrupt Queue Length [5-36]          */
102         u_int32_t       grcd;      /* Group Configuration Descriptor [5-16]  */
103         u_int32_t       mpd;       /* Memory Protection Descriptor [5-18]    */
104         u_int32_t       mld;       /* Message Length Descriptor [5-20]       */
105         u_int32_t       pcd;       /* Port Configuration Descriptor [5-19]   */
106         u_int32_t       __rbist;   /* Receive BIST status [5-4]              */
107         u_int32_t       __tbist;   /* Receive BIST status [5-4]              */
108 };
109
110 struct globalr {
111         u_int32_t       gbp;       /* Group Base Pointer */
112         u_int32_t       dacbp;     /* Dual Address Cycle Base Pointer */
113         u_int32_t       srd;       /* Service Request Descriptor */
114         u_int32_t       isd;       /* Interrupt Service Descriptor */
115         u_int32_t       __thp[28];   /* Transmit Head Pointer [5-29]         */
116         u_int32_t       __tmp[32];   /* Transmit Message Pointer [5-30]      */
117         u_int32_t       __rhp[32];   /* Receive Head Pointer [5-29]          */
118         u_int32_t       __rmp[32];   /* Receive Message Pointer [5-30]       */
119         u_int8_t        ttsm[128]; /* Time Slot Map [5-22]                   */
120         u_int8_t        tscm[256]; /* Subchannel Map [5-24]                  */
121         u_int32_t       tcct[32];  /* Channel Configuration [5-26]           */
122         u_int8_t        rtsm[128]; /* Time Slot Map [5-22]                   */
123         u_int8_t        rscm[256]; /* Subchannel Map [5-24]                  */
124         u_int32_t       rcct[32];  /* Channel Configuration [5-26]           */
125         u_int32_t       glcd;      /* Global Configuration Descriptor [5-10] */
126         u_int32_t       iqp;       /* Interrupt Queue Pointer [5-36]         */
127         u_int32_t       iql;       /* Interrupt Queue Length [5-36]          */
128         u_int32_t       grcd;      /* Group Configuration Descriptor [5-16]  */
129         u_int32_t       mpd;       /* Memory Protection Descriptor [5-18]    */
130         u_int32_t       mld;       /* Message Length Descriptor [5-20]       */
131         u_int32_t       pcd;       /* Port Configuration Descriptor [5-19]   */
132         u_int32_t       rbist;   /* Receive BIST status [5-4]              */
133         u_int32_t       tbist;   /* Receive BIST status [5-4]              */
134 };
135
136 /*
137  * Because the chan_group must be 2k aligned we create this super 
138  * structure so we can use the remaining 476 bytes for something useful
139  */
140
141 struct mycg {
142         struct groupr   cg;
143 };
144
145 struct mdesc {
146         u_int32_t       status;
147         u_int32_t       data;
148         u_int32_t       next;
149         /* Software only */
150         struct mbuf     *m;
151         struct mdesc    *snext;
152 };
153
154 #define NPORT   8
155
156 #define NHDLC   32
157
158 #define NIQD    32
159
160 struct softc;
161
162 struct schan {
163         enum {DOWN, UP} state;
164         struct softc    *sc;
165         int             chan;
166         u_int32_t       ts;
167         char            hookname[8];
168
169         hook_p          hook;
170
171         u_long          rx_drop;        /* mbuf allocation failures */
172         u_long          tx_limit;
173         u_long          tx_pending;
174         struct mdesc    *tx_next_md;    /* next MD */
175         struct mdesc    *tx_last_md;    /* last MD */
176         int             rx_last_md;     /* index to next MD */
177         int             nmd;            /* count of MD's. */
178
179         time_t          last_recv;
180         time_t          last_rdrop;
181         time_t          last_rxerr;
182         u_long          crc_error;
183         u_long          dribble_error;
184         u_long          long_error;
185         u_long          abort_error;
186         u_long          short_error;
187         u_long          txn, rxn;
188
189         time_t          last_xmit;
190         time_t          last_txerr;
191
192         time_t          last_txdrop;
193         u_long          tx_drop;
194
195 #if 0
196
197
198         u_long          rx_error;
199
200         u_long          overflow_error;
201
202         int             last_error;
203         int             prev_error;
204
205 #endif
206 };
207
208 enum framing {WHOKNOWS, E1, E1U, T1, T1U};
209 enum clocksource {EXT, INT};
210
211 struct softc {
212         enum framing framing;
213         enum clocksource clocksource;
214         int nhooks;
215         u_int32_t last;
216         struct csoftc *csc;
217         u_int32_t *ds8370;
218         void    *ds847x;
219         struct globalr *reg;
220         struct groupr *ram;
221         struct mycg *mycg;
222         struct mdesc *mdt[NHDLC];
223         struct mdesc *mdr[NHDLC];
224         node_p node;                    /* NG node */
225         char nodename[NG_NODESIZ];      /* NG nodename */
226         struct schan *chan[NHDLC];
227         u_long          cnt_ferr;
228         u_long          cnt_cerr;
229         u_long          cnt_lcv;
230         u_long          cnt_febe;
231         u_long          cnt_berr;
232         u_long          cnt_fred;
233         u_long          cnt_cofa;
234         u_long          cnt_sef;
235 };
236
237 /*
238  * SoftC for the entire card.
239  */
240
241 struct csoftc {
242         enum { C_IDLE, C_INIT, C_RUNNING, C_FAULT } state;
243
244         int     unit, bus, slot;
245         LIST_ENTRY(csoftc) list;
246
247         device_t f[2];
248         struct resource *irq[2];
249         void *intrhand[2];
250         vm_offset_t physbase[2];
251         u_char *virbase[2];
252
253         u_int creg, *cregp;
254         int nchan;
255         struct softc serial[NPORT];
256
257         struct globalr *reg;
258         struct globalr *ram;
259         u_int32_t iqd[NIQD];
260 };
261
262 /*
263  *
264  */
265
266 #define NG_NODETYPE     "lmc1504"
267
268 static  ng_constructor_t musycc_constructor;
269 static  ng_rcvmsg_t musycc_rcvmsg;
270 static  ng_shutdown_t musycc_shutdown;
271 static  ng_newhook_t musycc_newhook;
272 static  ng_connect_t musycc_connect;
273 static  ng_rcvdata_t musycc_rcvdata;
274 static  ng_disconnect_t musycc_disconnect;
275
276 static struct ng_type ngtypestruct = {
277         NG_VERSION,
278         NG_NODETYPE,
279         NULL, 
280         musycc_constructor,
281         musycc_rcvmsg,
282         musycc_shutdown,
283         musycc_newhook,
284         NULL,
285         musycc_connect,
286         musycc_rcvdata,
287         musycc_rcvdata,
288         musycc_disconnect,
289         NULL
290 };
291
292 /*
293  *
294  */
295
296 static u_int32_t
297 parse_ts(const char *s, int *nbit)
298 {
299         unsigned r;
300         int i, j;
301         char *p;
302
303         r = 0;
304         j = -1;
305         *nbit = 0;
306         while(*s) {
307                 i = strtol(s, &p, 0);
308                 if (i < 0 || i > 31)
309                         return (0);
310                 while (j != -1 && j < i) {
311                         r |= 1 << j++;
312                         (*nbit)++;
313                 }
314                 j = -1;
315                 r |= 1 << i;
316                 (*nbit)++;
317                 if (*p == ',') {
318                         s = p + 1;
319                         continue;
320                 } else if (*p == '-') {
321                         j = i + 1;
322                         s = p + 1;
323                         continue;
324                 } else if (!*p) {
325                         break;
326                 } else {
327                         return (0);
328                 }
329         }
330         return (r);
331 }
332
333 /*
334  *
335  */
336
337
338 static LIST_HEAD(, csoftc) sc_list = LIST_HEAD_INITIALIZER(&sc_list);
339
340 static void
341 poke_847x(void *dummy)
342 {
343         static int count;
344         int i;
345         struct csoftc *csc;
346
347         timeout(poke_847x, NULL, 1);
348         LIST_FOREACH(csc, &sc_list, list)  {
349                 count++;
350                 i = (csc->creg >> 24 & 0xf);
351                 csc->creg &= ~0xf000000;
352                 i++;
353                 csc->creg |= (i & 0xf) << 24;
354                 *csc->cregp = csc->creg;
355 #if 0
356                 for (i = 0; i < sc->nchan; i++) {
357                         if (sc->serial[i].last == 0xffffffff) {
358                                 sc->serial[i].reg->srd = 0;
359                                 sc->serial[i].last = 0;
360                                 return;
361                         }
362                 }
363 #endif
364         }
365 }
366
367 static void
368 init_card(struct csoftc *csc)
369 {
370
371         kprintf("init_card(%p)\n", csc);
372
373         csc->state = C_INIT;
374         csc->reg->srd = 0x100;
375         tsleep(csc, PCATCH, "icard", hz / 10);
376         csc->reg->gbp = vtophys(csc->ram);
377         csc->ram->glcd = 0x3f30;        /* XXX: designer magic */
378         
379         csc->ram->iqp = vtophys(csc->iqd);
380         csc->ram->iql = NIQD - 1;
381         csc->ram->dacbp = 0;            /* 32bit only */
382
383         csc->reg->srd = csc->serial[0].last = 0x400;
384         tsleep(&csc->serial[0].last, PCATCH, "con1", hz);
385         timeout(poke_847x, NULL, 1);
386         csc->state = C_RUNNING;
387 }
388
389 static void
390 init_ctrl(struct softc *sc)
391 {
392         int i;
393
394         kprintf("init_ctrl(%p) [%s] [%08x]\n", sc, sc->nodename, sc->csc->reg->glcd);
395         init_8370(sc);
396         tsleep(sc, PCATCH, "ds8370", hz);
397         kprintf("%s: glcd: [%08x]\n", sc->nodename, sc->csc->reg->glcd);
398         sc->reg->gbp = vtophys(sc->ram);
399         sc->ram->grcd =  0x00000001;    /* RXENBL */
400         sc->ram->grcd |= 0x00000002;    /* TXENBL */
401         sc->ram->grcd |= 0x00000004;    /* SUBDSBL */
402         if (sc->framing == E1 || sc->framing == T1)
403                 sc->ram->grcd |= 0x00000008;    /* OOFABT */
404         else
405                 sc->ram->grcd |= 0x00000000;    /* !OOFABT */
406
407         sc->ram->grcd |= 0x00000020;    /* MSKCOFA */
408
409         sc->ram->grcd |= 0x00000440;    /* POLLTH=1 */
410
411         sc->ram->mpd = 0;               /* Memory Protection NI [5-18] */
412
413         sc->ram->pcd =  0x0000001;      /* PORTMD=1 (E1/32ts) */
414         sc->ram->pcd |= 1 << 5;         /* TSYNC_EDGE */
415         sc->ram->pcd |= 1 << 9;         /* TRITX */
416
417         /* Message length descriptor */
418         /* XXX: MTU */
419         sc->ram->mld = 1600;
420         sc->ram->mld |= (1600 << 16);
421
422         for (i = 0; i < NHDLC; i++) {
423                 sc->ram->ttsm[i] = 0;
424                 sc->ram->rtsm[i] = 0;
425         }
426         sc->reg->srd = sc->last = 0x500;
427         tsleep(&sc->last, PCATCH, "con1", hz);
428         sc->reg->srd = sc->last = 0x520;
429         tsleep(&sc->last, PCATCH, "con1", hz);
430 }
431
432 /*
433  *
434  */
435
436 static void
437 status_chans(struct softc *sc, char *s)
438 {
439         int i;
440         struct schan *scp;
441
442         s += strlen(s);
443         for (i = 0; i < NHDLC; i++) {
444                 scp = sc->chan[i];
445                 if (scp == NULL)
446                         continue;
447                 ksprintf(s + strlen(s), "c%2d:", i);
448                 ksprintf(s + strlen(s), " ts %08x", scp->ts);
449                 ksprintf(s + strlen(s), " RX %lus/%lus",
450                     time_second - scp->last_recv, time_second - scp->last_rxerr);
451                 ksprintf(s + strlen(s), " TX %lus/%lus/%lus",
452                     time_second - scp->last_xmit, 
453                     time_second - scp->last_txerr,
454                     time_second - scp->last_txdrop);
455                 ksprintf(s + strlen(s), " TXdrop %lu Pend %lu", 
456                     scp->tx_drop,
457                     scp->tx_pending);
458                 ksprintf(s + strlen(s), " CRC %lu Dribble %lu Long %lu Short %lu Abort %lu",
459                     scp->crc_error,
460                     scp->dribble_error,
461                     scp->long_error,
462                     scp->short_error,
463                     scp->abort_error);
464                 ksprintf(s + strlen(s), "\n TX: %lu RX: %lu\n",
465                     scp->txn, scp->rxn);
466         }
467 }
468
469
470 /*
471  *
472  */
473
474 static void
475 status_8370(struct softc *sc, char *s)
476 {
477         u_int32_t *p = sc->ds8370;
478
479         s += strlen(s);
480         ksprintf(s, "Framer: "); s += strlen(s);
481         switch (sc->framing) {
482                 case WHOKNOWS: ksprintf(s, "(unconfigured)\n"); break;
483                 case E1: ksprintf(s, "(e1)\n"); break;
484                 case E1U: ksprintf(s, "(e1u)\n"); break;
485                 case T1: ksprintf(s, "(t1)\n"); break;
486                 case T1U: ksprintf(s, "(t1u)\n"); break;
487                 default: ksprintf(s, "(mode %d XXX?)\n", sc->framing); break;
488         }
489         s += strlen(s);
490         ksprintf(s, "    Red alarms:"); s += strlen(s);
491         if (p[0x47] & 0x08) { ksprintf(s, " ALOS"); s += strlen(s); }
492         if (p[0x47] & 0x04) { ksprintf(s, " LOS"); s += strlen(s); }
493         if (sc->framing == E1 || sc->framing == T1) {
494                 if (p[0x47] & 0x02) { ksprintf(s, " LOF"); s += strlen(s); }
495         }
496         ksprintf(s, "\n    Yellow alarms:"); s += strlen(s);
497         if (p[0x47] & 0x80) { ksprintf(s, " RMYEL"); s += strlen(s); }
498         if (p[0x47] & 0x40) { ksprintf(s, " RYEL"); s += strlen(s); }
499         ksprintf(s, "\n    Blue alarms:"); s += strlen(s);
500         if (p[0x47] & 0x10) { ksprintf(s, " AIS"); s += strlen(s); }
501         ksprintf(s, "\n"); s += strlen(s);
502         ksprintf(s, "\n    Various alarms:"); s += strlen(s);
503         if (p[0x48] & 0x10) { ksprintf(s, " TSHORT"); s += strlen(s); }
504         ksprintf(s, "\n    Counters:"); s += strlen(s);
505         if (sc->framing == E1) {
506                 ksprintf(s, " FERR=%lu", sc->cnt_ferr); s += strlen(s);
507         }
508         ksprintf(s, " CERR=%lu", sc->cnt_cerr); s += strlen(s);
509         ksprintf(s, " LCV=%lu",  sc->cnt_lcv); s += strlen(s);
510         ksprintf(s, " FEBE=%lu", sc->cnt_febe); s += strlen(s);
511         ksprintf(s, " BERR=%lu", sc->cnt_berr); s += strlen(s);
512         ksprintf(s, " FRED=%lu", sc->cnt_fred); s += strlen(s);
513         ksprintf(s, " COFA=%lu", sc->cnt_cofa); s += strlen(s);
514         ksprintf(s, " SEF=%lu", sc->cnt_sef); s += strlen(s);
515         ksprintf(s, "\n"); s += strlen(s);
516 }
517
518 static void
519 dump_8370(struct softc *sc, char *s, int offset)
520 {
521         int i, j;
522         u_int32_t *p = sc->ds8370;
523
524         s += strlen(s);
525         for (i = 0; i < 0x100; i += 16) {
526                 ksprintf(s, "%03x: ", i + offset);
527                 s += strlen(s);
528                 for (j = 0; j < 0x10; j ++) {
529                         ksprintf(s, " %02x", p[i + j + offset] & 0xff);
530                         s += strlen(s);
531                 }
532                 ksprintf(s, "\n");
533                 s += strlen(s);
534         }
535 }
536
537 static void
538 init_8370(struct softc *sc)
539 {
540         int i;
541         u_int32_t *p = sc->ds8370;
542
543         p[0x001] = 0x80; /* CR0 - Reset */
544         DELAY(20);
545         p[0x001] = 0x00; /* CR0 - E1, RFRAME: FAS only */
546         DELAY(20);
547         if (sc->clocksource == INT) 
548                 p[0x002] = 0x40; /* JAT_CR - XXX */
549         else
550                 p[0x002] = 0x20; /* JAT_CR - XXX */
551         p[0x00D] = 0x01; /* IER6 - ONESEC */
552         p[0x014] = 0x00; /* LOOP - */
553         p[0x015] = 0x00; /* DL3_TS - */
554         p[0x016] = 0x00; /* DL3_BIT - */
555         p[0x017] = 0x00; /* DL3_BIT - */
556         p[0x018] = 0xFF; /* PIO - XXX */
557         p[0x019] = 0x3c; /* POE - CLADO_OE|RCKO_OE */
558         if (sc->clocksource == INT)
559                 p[0x01A] = 0x37; /* CMUX - RSBCKI(RSBCKI), TSBCKI(CLADO), CLADO(RCKO), TCKI(CLADO) */
560         else
561                 p[0x01A] = 0x37; /* CMUX - RSBCKI(RSBCKI), TSBCKI(RSBCKI), CLADO(RCKO), TCKI(RCKO) */
562
563         /* I.431/G.775 */
564         p[0x020] = 0x41; /* LIU_CR - SQUELCH */
565         p[0x022] = 0xb1; /* RLIU_CR - */
566         p[0x024] = 0x1d; /* VGA_MAX - */
567         p[0x027] = 0xba; /* DSLICE - */
568         p[0x028] = 0xda; /* EQ_OUT - */
569         p[0x02a] = 0xa6; /* PRE_EQ - */
570
571         if (sc->framing == E1U || sc->framing == T1U)
572                 p[0x040] = 0x49; /* RCRO - XXX */
573         else
574                 p[0x040] = 0x09; /* RCRO - XXX */
575
576         p[0x041] = 0x00; /* RPATT - XXX */
577         p[0x045] = 0x00; /* RALM - XXX */
578         p[0x046] = 0x05; /* LATCH - LATCH_CNT|LATCH_ALM */
579
580         p[0x068] = 0x4c; /* TLIU_CR - TERM|Pulse=6 */
581         p[0x070] = 0x04; /* TCR0 - TFRAME=4 */
582
583         if (sc->framing == E1U || sc->framing == T1U)
584                 p[0x071] = 0x41; /* TCR1 - TZCS */
585         else
586                 p[0x071] = 0x51; /* TCR1 - TZCS */
587
588         if (sc->framing == E1U || sc->framing == T1U)
589                 p[0x072] = 0x00;
590         else
591                 p[0x072] = 0x1b; /* TCR1 - INS_YEL|INS_MF|INS_CRC|INS_FBIT */
592
593         p[0x073] = 0x00; /* TERROR */
594         p[0x074] = 0x00; /* TMAN */
595
596         if (sc->framing == E1U || sc->framing == T1U)
597                 p[0x075] = 0x0; /* TALM */
598         else
599                 p[0x075] = 0x10; /* TALM - AUTO_YEL */
600
601         p[0x076] = 0x00; /* TPATT */
602         p[0x077] = 0x00; /* TLP */
603
604         p[0x090] = 0x05; /* CLAD_CR - XXX */
605         p[0x091] = 0x01; /* CSEL - 2048kHz */
606
607         if (sc->framing == E1U || sc->framing == T1U) {
608                 p[0x0a0] = 0x00;
609                 p[0x0a6] = 0x00;
610                 p[0x0b1] = 0x00;
611         }
612
613         p[0x0d0] = 0x46; /* SBI_CR - SBI=6 */
614         p[0x0d1] = 0x70; /* RSB_CR - XXX */
615         p[0x0d2] = 0x00; /* RSYNC_BIT - 0 */
616         p[0x0d3] = 0x00; /* RSYNC_TS - 0 */
617         p[0x0d4] = 0x30; /* TSB_CR - XXX */
618         p[0x0d5] = 0x00; /* TSYNC_BIT - 0 */
619         p[0x0d6] = 0x00; /* TSYNC_TS - 0 */
620         if (sc->framing == E1U || sc->framing == T1U) 
621                 p[0x0d7] = 0x05; /* RSIG_CR - 0  | FRZ_OFF*/
622         else 
623                 p[0x0d7] = 0x01; /* RSIG_CR - 0 */
624         p[0x0d8] = 0x00; /* RSIG_FRM - 0 */
625         for (i = 0; i < 32; i ++) {
626                 p[0x0e0 + i] = 0x0d; /* SBC$i - RINDO|TINDO|ASSIGN */
627                 p[0x100 + i] = 0x00; /* TPC$i - 0 */
628                 p[0x180 + i] = 0x00; /* RPC$i - 0 */
629         }
630 }
631
632 /*
633  * Interrupts
634  */
635
636 static void
637 musycc_intr0_tx_eom(struct softc *sc, int ch)
638 {
639         struct schan *sch;
640         struct mdesc *md;
641
642         sch = sc->chan[ch];
643         if (sch == NULL || sch->state != UP) {
644                 /* XXX: this should not happen once the driver is done */
645                 kprintf("Xmit packet on uninitialized channel %d\n", ch);
646         }
647         if (sc->mdt[ch] == NULL)
648                 return;         /* XXX: can this happen ? */
649         for (;;) {
650                 md = sch->tx_last_md;
651                 if (md->status == 0)
652                         break;
653                 if (md->status & 0x80000000)
654                         break;          /* Not our mdesc, done */
655                 sch->tx_last_md = md->snext;
656                 md->data = 0;
657                 if (md->m != NULL) {
658                         sch->tx_pending -= md->m->m_pkthdr.len;
659                         m_freem(md->m);
660                         md->m = NULL;
661                 }
662                 md->status = 0;
663         }
664 }
665
666 /*
667  * Receive interrupt on controller *sc, channel ch
668  *
669  * We perambulate the Rx descriptor ring until we hit
670  * a mdesc which isn't ours to take.
671  */
672
673 static void
674 musycc_intr0_rx_eom(struct softc *sc, int ch)
675 {
676         u_int32_t status, error;
677         struct schan *sch;
678         struct mbuf *m, *m2;
679         struct mdesc *md;
680
681         sch = sc->chan[ch];
682         if (sch == NULL || sch->state != UP) {
683                 /* XXX: this should not happen once the driver is done */
684                 kprintf("Received packet on uninitialized channel %d\n", ch);
685                 return;
686         }
687         if (sc->mdr[ch] == NULL)
688                 return;         /* XXX: can this happen ? */
689         for (;;) {
690                 md = &sc->mdr[ch][sch->rx_last_md];
691                 status = md->status;
692                 if (!(status & 0x80000000))
693                         break;          /* Not our mdesc, done */
694                 m = md->m;
695                 m->m_len = m->m_pkthdr.len = status & 0x3fff;
696                 error = (status >> 16) & 0xf;
697                 if (error == 0) {
698                         MGETHDR(m2, MB_DONTWAIT, MT_DATA);
699                         if (m2 != NULL) {
700                                 MCLGET(m2, MB_DONTWAIT);
701                                 if((m2->m_flags & M_EXT) != 0) {
702                                         /* Substitute the mbuf+cluster. */
703                                         md->m = m2;
704                                         md->data = vtophys(m2->m_data);
705                                         /* Pass the received mbuf upwards. */
706                                         sch->last_recv = time_second;
707                                         ng_queue_data(sch->hook, m, NULL);
708                                 } else {
709                                         /*
710                                          * We didn't get a mbuf cluster,
711                                          * drop received packet, free the
712                                          * mbuf we cannot use and recycle
713                                          * the mbuf+cluster we already had.
714                                          */
715                                         m_freem(m2);
716                                         sch->last_rdrop = time_second;
717                                         sch->rx_drop++;
718                                 }
719                         } else {
720                                 /*
721                                  * We didn't get a mbuf, drop received packet
722                                  * and recycle the "old" mbuf+cluster.
723                                  */
724                                 sch->last_rdrop = time_second;
725                                 sch->rx_drop++;
726                         }
727                 } else if (error == 9) {
728                         sch->last_rxerr = time_second;
729                         sch->crc_error++;
730                 } else if (error == 10) {
731                         sch->last_rxerr = time_second;
732                         sch->dribble_error++;
733                 } else if (error == 11) {
734                         sch->last_rxerr = time_second;
735                         sch->abort_error++;
736                 } else if (error == 12) {
737                         sch->last_rxerr = time_second;
738                         sch->long_error++;
739                 } else {
740                         sch->last_rxerr = time_second;
741                         /* Receive error, print some useful info */
742                         kprintf("%s %s: RX 0x%08x ", sch->sc->nodename, 
743                             sch->hookname, status);
744                         /* Don't print a lot, just the begining will do */
745                         if (m->m_len > 16)
746                                 m->m_len = m->m_pkthdr.len = 16;
747                         m_print(m);
748                         kprintf("\n");
749                 }
750                 md->status = 1600;      /* XXX: MTU */
751                 /* Check next mdesc in the ring */
752                 if (++sch->rx_last_md >= sch->nmd)
753                         sch->rx_last_md = 0;
754         }
755 }
756
757 static void
758 musycc_intr0(void *arg)
759 {
760         int i, j, g, ch, ev, er;
761         struct csoftc *csc;
762         u_int32_t u, u1, n, c;
763         struct softc *sc;
764
765         csc = arg;
766
767         for (;;) {
768                 u = csc->reg->isd;
769                 c = u & 0x7fff;
770                 n = u >> 16;
771                 if (c == 0)
772                         return;
773                 if (debug & 1)
774                         kprintf("%s: IRQ: %08x n = %d c = %d\n", csc->serial[0].nodename, u, n, c);
775                 for (i = 0; i < c; i++) {
776                         j = (n + i) % NIQD;
777                         u1 = csc->iqd[j];
778                         g = (u1 >> 29) & 0x3;
779                         g |= (u1 >> (14-2)) & 0x4;
780                         ch = (u1 >> 24) & 0x1f;
781                         ev = (u1 >> 20) & 0xf;
782                         er = (u1 >> 16) & 0xf;
783                         sc = &csc->serial[g];
784                         if ((debug & 2) || er) {
785                                 kprintf("%08x %d", u1, g);
786                                 kprintf("/%s", u1 & 0x80000000 ? "T" : "R");
787                                 kprintf("/%02d", ch);
788                                 kprintf(" %02d", ev);
789                                 kprintf(":%02d", er);
790                                 kprintf("\n");
791                         }
792                         switch (ev) {
793                         case 1: /* SACK         Service Request Acknowledge         */
794 #if 0
795                                 kprintf("%s: SACK: %08x group=%d", sc->nodename, csc->iqd[j], g);
796                                 kprintf("/%s", csc->iqd[j] & 0x80000000 ? "T" : "R");
797                                 kprintf(" cmd %08x (%08x) \n", sc->last, sc->reg->srd);
798 #endif
799                                 sc->last = 0xffffffff;
800                                 wakeup(&sc->last);
801                                 break;
802                         case 5: /* CHABT        Change To Abort Code (0x7e -> 0xff) */
803                         case 6: /* CHIC         Change To Idle Code (0xff -> 0x7e)  */
804                                 break;
805                         case 3: /* EOM          End Of Message                      */
806                                 if (csc->iqd[j] & 0x80000000)
807                                         musycc_intr0_tx_eom(sc, ch);
808                                 else
809                                         musycc_intr0_rx_eom(sc, ch);
810                                 break;
811                         case 0:
812                                 if (er == 13) { /* SHT */
813                                         sc->chan[ch]->last_rxerr = time_second;
814                                         sc->chan[ch]->short_error++;
815                                         break;
816                                 }
817                         default:
818                                 musycc_intr0_tx_eom(sc, ch);
819                                 musycc_intr0_rx_eom(sc, ch);
820 #if 1
821                                 kprintf("huh ? %08x %d", u1, g);
822                                 kprintf("/%s", u1 & 0x80000000 ? "T" : "R");
823                                 kprintf("/%02d", ch);
824                                 kprintf(" %02d", ev);
825                                 kprintf(":%02d", er);
826                                 kprintf("\n");
827 #endif
828                         }
829                         csc->iqd[j] = 0xffffffff;
830                         j++;
831                         j %= NIQD;
832                         csc->reg->isd = j << 16;
833                 }
834         }
835 }
836
837 static void
838 musycc_intr1(void *arg)
839 {
840         int i;
841         struct csoftc *csc;
842         struct softc *sc;
843         u_int32_t *u;
844         u_int8_t irr;
845         
846         csc = arg;
847
848         for (i = 0; i < csc->nchan; i++) {
849                 sc = &csc->serial[i];
850                 u = sc->ds8370;
851                 irr = u[3];
852                 if (irr == 0)
853                         continue;
854                 if (u[0x5] & 1) { /* ONESEC */
855                         sc->cnt_ferr +=  u[0x50] & 0xff;
856                         sc->cnt_ferr += (u[0x51] & 0xff) << 8;
857                         sc->cnt_cerr +=  u[0x52] & 0xff;
858                         sc->cnt_cerr += (u[0x53] & 0xff) << 8;
859                         sc->cnt_lcv  +=  u[0x54] & 0xff;
860                         sc->cnt_lcv  += (u[0x55] & 0xff) << 8;
861                         sc->cnt_febe +=  u[0x56] & 0xff;
862                         sc->cnt_febe += (u[0x57] & 0xff) << 8;
863                         sc->cnt_berr +=  u[0x58] & 0xff;
864                         sc->cnt_berr += (u[0x59] & 0xff) << 8;
865                         sc->cnt_fred += (u[0x5a] & 0xf0) >> 4;
866                         sc->cnt_cofa += (u[0x5a] & 0x0c) >> 2;
867                         sc->cnt_sef  +=  u[0x5a] & 0x03;
868                 }
869                 if (debug & 4) {
870                         int j;
871
872                         kprintf("musycc_intr1:%d %02x", i, irr);
873                         for (j = 4; j < 0x14; j++)
874                                 kprintf(" %02x", u[j] & 0xff);
875                         kprintf("\n");
876                 }
877         }
878 }
879
880 /*
881  * NetGraph Stuff
882  */
883
884 static int
885 musycc_constructor(node_p *nodep)
886 {
887
888         return (EINVAL);
889 }
890
891 static int
892 musycc_shutdown(node_p nodep)
893 {
894
895         return (EINVAL);
896 }
897
898 static void
899 musycc_config(node_p node, char *set, char *ret)
900 {
901         struct softc *sc;
902         struct csoftc *csc;
903         enum framing wframing;
904         int i;
905
906         sc = node->private;
907         csc = sc->csc;
908         if (csc->state == C_IDLE) 
909                 init_card(csc);
910         while (csc->state != C_RUNNING)
911                 tsleep(&csc->state, PCATCH, "crun", hz/10);
912         if (set != NULL) {
913                 if (!strncmp(set, "line ", 5)) {
914                         wframing = sc->framing;
915                         if (!strcmp(set, "line e1")) {
916                                 wframing = E1;
917                         } else if (!strcmp(set, "line e1u")) {
918                                 wframing = E1U;
919                         } else {
920                                 strcat(ret, "ENOGROK\n");
921                                 return;
922                         }
923                         if (wframing == sc->framing)
924                                 return;
925                         if (sc->nhooks > 0) {
926                                 ksprintf(ret, "Cannot change line when %d hooks open\n", sc->nhooks);
927                                 return;
928                         }
929                         sc->framing = wframing;
930                         init_ctrl(sc);
931                         return;
932                 }
933                 if (!strcmp(set, "clock source internal")) {
934                         sc->clocksource = INT;
935                         init_ctrl(sc);
936                 } else if (!strcmp(set, "clock source line")) {
937                         sc->clocksource = EXT;
938                         init_ctrl(sc);
939                 } else if (!strcmp(set, "show 8370 0")) {
940                         dump_8370(sc, ret, 0);
941                 } else if (!strcmp(set, "show 8370 1")) {
942                         dump_8370(sc, ret, 0x100);
943                 } else if (!strncmp(set, "creg", 4)) {
944                         i = strtol(set + 5, 0, 0);
945                         kprintf("set creg %d\n", i);
946                         csc->creg = 0xfe | (i << 24);
947                         *csc->cregp = csc->creg;
948 /*
949                 } else if (!strcmp(set, "reset")) {
950                         reset_group(sc, ret);
951                 } else if (!strcmp(set, "reset all")) {
952                         reset_card(sc, ret);
953 */
954                 } else {
955                         kprintf("%s CONFIG SET [%s]\n", sc->nodename, set);
956                         goto barf;
957                 }               
958
959                 return;
960         }
961         if (sc->framing == E1)
962                 strcat(ret, "line e1\n");
963         else if (sc->framing == E1U)
964                 strcat(ret, "line e1u\n");
965         if (sc->clocksource == INT)
966                 strcat(ret, "clock source internal\n");
967         else
968                 strcat(ret, "clock source line\n");
969         return;
970 barf:
971         strcpy(ret, "Syntax Error\n");
972         strcat(ret, "\tline {e1|e1u}\n");
973         strcat(ret, "\tshow 8370 {0|1}\n");
974         return;
975 }
976
977 /*
978  * Handle status and config enquiries.
979  * Respond with a synchronous response.
980  */
981 static int
982 musycc_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp)
983 {
984         struct softc *sc;
985         char *s, *r;
986
987         sc = node->private;
988
989         if (msg->header.typecookie != NGM_GENERIC_COOKIE)
990                 goto out;
991
992         if (msg->header.cmd == NGM_TEXT_STATUS) {
993                 NG_MKRESPONSE(*resp, msg, 
994                     sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT);
995                 if (*resp == NULL) {
996                         kfree(msg, M_NETGRAPH);
997                         return (ENOMEM);
998                 }
999                 s = (char *)(*resp)->data;
1000                 status_8370(sc, s);
1001                 status_chans(sc,s);
1002                 (*resp)->header.arglen = strlen(s) + 1;
1003                 kfree(msg, M_NETGRAPH);
1004                 return (0);
1005         } else if (msg->header.cmd == NGM_TEXT_CONFIG) {
1006                 if (msg->header.arglen) {
1007                         s = (char *)msg->data;
1008                 } else {
1009                         s = NULL;
1010                 }
1011                 
1012                 NG_MKRESPONSE(*resp, msg, 
1013                     sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT);
1014                 if (*resp == NULL) {
1015                         kfree(msg, M_NETGRAPH);
1016                         return (ENOMEM);
1017                 }
1018                 r = (char *)(*resp)->data;
1019                 *r = '\0';
1020                 musycc_config(node, s, r);
1021                 (*resp)->header.arglen = strlen(r) + 1;
1022                 kfree(msg, M_NETGRAPH);
1023                 return (0);
1024         }
1025
1026 out:
1027         if (resp)
1028                 *resp = NULL;
1029         kfree(msg, M_NETGRAPH);
1030         return (EINVAL);
1031 }
1032
1033 static int
1034 musycc_newhook(node_p node, hook_p hook, const char *name)
1035 {
1036         struct softc *sc;
1037         struct csoftc *csc;
1038         struct schan *sch;
1039         u_int32_t ts, chan;
1040         int nbit;
1041
1042         sc = node->private;
1043         csc = sc->csc;
1044
1045         while (csc->state != C_RUNNING)
1046                 tsleep(&csc->state, PCATCH, "crun", hz/10);
1047
1048         if (sc->framing == WHOKNOWS)
1049                 return (EINVAL);
1050
1051         if (name[0] != 't' || name[1] != 's')
1052                 return (EINVAL);
1053         ts = parse_ts(name + 2, &nbit);
1054         if (ts == 0)
1055                 return (EINVAL);
1056         chan = ffs(ts) - 1;
1057
1058         if (sc->framing == E1U && nbit == 32)
1059                 ;
1060         else if (sc->framing == T1U && nbit == 24)
1061                 ;
1062         else if (ts & 1)
1063                 return (EINVAL);
1064                 
1065         if (sc->chan[chan] == NULL) {
1066                 sch = kmalloc(sizeof(*sch), M_MUSYCC, M_WAITOK | M_ZERO);
1067                 sch->sc = sc;
1068                 sch->state = DOWN;
1069                 sch->chan = chan;
1070                 ksprintf(sch->hookname, name);  /* XXX overflow ? */
1071                 sc->chan[chan] = sch;
1072         } else if (sc->chan[chan]->state == UP) {
1073                 return (EBUSY);
1074         }
1075         sc->nhooks++;
1076         sch = sc->chan[chan];
1077         sch->ts = ts;
1078         sch->hook = hook;
1079         sch->tx_limit = nbit * 8;
1080         hook->private = sch;
1081         return(0);
1082 }
1083
1084 static int
1085 musycc_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
1086 {
1087
1088         struct softc *sc;
1089         struct csoftc *csc;
1090         struct schan *sch;
1091         struct mdesc *md, *md0;
1092         u_int32_t ch, u, u0, len;
1093         struct mbuf *m2;
1094
1095         sch = hook->private;
1096         sc = sch->sc;
1097         csc = sc->csc;
1098         ch = sch->chan;
1099
1100         if (csc->state != C_RUNNING) {
1101                 kprintf("csc->state = %d\n", csc->state);
1102                 NG_FREE_DATA(m, meta);
1103                 return (0);
1104         }
1105
1106         NG_FREE_META(meta);
1107         meta = NULL;
1108
1109         if (sch->state != UP) {
1110                 kprintf("sch->state = %d\n", sch->state);
1111                 NG_FREE_DATA(m, meta);
1112                 return (0);
1113         } 
1114         if (sch->tx_pending + m->m_pkthdr.len > sch->tx_limit * maxlatency) {
1115                 sch->tx_drop++;
1116                 sch->last_txdrop = time_second;
1117                 NG_FREE_DATA(m, meta);
1118                 return (0);
1119         }
1120
1121         /* find out if we have enough txmd's */
1122         m2 = m;
1123         md = sch->tx_next_md;
1124         for (len = m2->m_pkthdr.len; len; m2 = m2->m_next) {
1125                 if (m2->m_len == 0)
1126                         continue;
1127                 if (md->status != 0) {
1128                         sch->tx_drop++;
1129                         sch->last_txdrop = time_second;
1130                         NG_FREE_DATA(m, meta);
1131                         return (0);
1132                 }
1133                 len -= m2->m_len;
1134                 md = md->snext;
1135         }
1136
1137         m2 = m;
1138         md = md0 = sch->tx_next_md;
1139         u0 = 0;
1140         for (len = m->m_pkthdr.len; len > 0; m = m->m_next) {
1141                 if (m->m_len == 0)
1142                         continue;
1143                 if (md->status != 0) {
1144                         kprintf("Out of tx md(2)\n");
1145                         sch->last_txerr = time_second;
1146                         sch->tx_drop++;
1147                         sch->last_txdrop = time_second;
1148                         NG_FREE_DATA(m, meta);
1149                         break;
1150                 }
1151
1152                 md->data = vtophys(m->m_data);
1153                 if (md == md0)
1154                         u = 0x00000000; /* OWNER = CPU */
1155                 else
1156                         u = 0x80000000; /* OWNER = MUSYCC */
1157                 u |= m->m_len;
1158                 len -= m->m_len;
1159                 if (len > 0) {
1160                         md->m = NULL;
1161                         if (md == md0)
1162                                 u0 = u;
1163                         else
1164                                 md->status = u;
1165                         md = md->snext;
1166                         continue;
1167                 }
1168                 u |= 0x20000000;        /* EOM */
1169                 md->m = m2;
1170                 sch->tx_pending += m2->m_pkthdr.len;
1171                 if (md == md0) {
1172                         u |= 0x80000000;        /* OWNER = MUSYCC */
1173                         md->status = u;
1174                 } else {
1175                         md->status = u;
1176                         md0->status = u0 | 0x80000000; /* OWNER = MUSYCC */
1177                 }
1178                 sch->last_xmit = time_second;
1179                 sch->tx_next_md = md->snext;
1180         }
1181         sch->txn++;
1182         return (0);
1183 }
1184
1185 static int
1186 musycc_connect(hook_p hook)
1187 {
1188         struct softc *sc;
1189         struct csoftc *csc;
1190         struct schan *sch;
1191         int nts, nbuf, i, nmd, ch;
1192         struct mbuf *m;
1193
1194         sch = hook->private;
1195         sc = sch->sc;
1196         csc = sc->csc;
1197         ch = sch->chan;
1198
1199         while (csc->state != C_RUNNING)
1200                 tsleep(&csc->state, PCATCH, "crun", hz/10);
1201
1202         if (sch->state == UP)
1203                 return (0);
1204         sch->state = UP;
1205
1206         /* Setup the Time Slot Map */
1207         nts = 0;
1208         for (i = ch; i < 32; i++) {
1209                 if (sch->ts & (1 << i)) {
1210                         sc->ram->rtsm[i] = ch | (4 << 5);
1211                         sc->ram->ttsm[i] = ch | (4 << 5);
1212                         nts++;          
1213                 }
1214         }
1215
1216         /* 
1217          * Find the length of the first run of timeslots.
1218          * XXX: find the longest instead.
1219          */
1220         nbuf = 0;
1221         for (i = ch; i < 32; i++) {
1222                 if (sch->ts & (1 << i))
1223                         nbuf++;
1224                 else
1225                         break;
1226         }
1227                 
1228         kprintf("Connect ch= %d ts= %08x nts= %d nbuf = %d\n", 
1229             ch, sch->ts, nts, nbuf);
1230
1231         /* Reread the Time Slot Map */
1232         sc->reg->srd = sc->last = 0x1800;
1233         tsleep(&sc->last, PCATCH, "con1", hz);
1234         sc->reg->srd = sc->last = 0x1820;
1235         tsleep(&sc->last, PCATCH, "con2", hz);
1236
1237         /* Set the channel mode */
1238         sc->ram->tcct[ch] = 0x2800; /* HDLC-FCS16 | MAXSEL[2] */
1239         sc->ram->rcct[ch] = 0x2800; /* HDLC-FCS16 | MAXSEL[2] */
1240
1241         /*
1242          * Allocate the FIFO space
1243          * We don't do subchanneling so we can use 128 dwords [4-13]
1244          */
1245         sc->ram->tcct[ch] |= (1 + 2 * (nbuf - 1)) << 16; /* BUFFLEN */
1246         sc->ram->rcct[ch] |= (1 + 2 * (nbuf - 1)) << 16; /* BUFFLEN */
1247         sc->ram->tcct[ch] |= ((ch * 2) << 24);   /* BUFFLOC */
1248         sc->ram->rcct[ch] |= ((ch * 2) << 24);   /* BUFFLOC */
1249
1250         /* Reread the Channel Configuration Descriptor for this channel */
1251         sc->reg->srd = sc->last = 0x0b00 + ch;
1252         tsleep(&sc->last, PCATCH, "con3", hz);
1253         sc->reg->srd = sc->last = 0x0b20 + ch;
1254         tsleep(&sc->last, PCATCH, "con4", hz);
1255
1256         /*
1257          * Figure out how many receive buffers we want:  10 + nts * 2
1258          *  1 timeslot,  50 bytes packets -> 68msec
1259          * 31 timeslots, 50 bytes packets -> 14msec
1260          */
1261         sch->nmd = nmd = 200 + nts * 4;
1262         sch->rx_last_md = 0;
1263         sc->mdt[ch] = kmalloc(sizeof(struct mdesc) * nmd, M_MUSYCC, M_WAITOK);
1264         sc->mdr[ch] = kmalloc(sizeof(struct mdesc) * nmd, M_MUSYCC, M_WAITOK);
1265         for (i = 0; i < nmd; i++) {
1266                 if (i == nmd - 1) {
1267                         sc->mdt[ch][i].snext = &sc->mdt[ch][0];
1268                         sc->mdt[ch][i].next = vtophys(sc->mdt[ch][i].snext);
1269                         sc->mdr[ch][i].snext = &sc->mdr[ch][0];
1270                         sc->mdr[ch][i].next = vtophys(sc->mdr[ch][i].snext);
1271                 } else {
1272                         sc->mdt[ch][i].snext = &sc->mdt[ch][i + 1];
1273                         sc->mdt[ch][i].next = vtophys(sc->mdt[ch][i].snext);
1274                         sc->mdr[ch][i].snext = &sc->mdr[ch][i + 1];
1275                         sc->mdr[ch][i].next = vtophys(sc->mdr[ch][i].snext);
1276                 }
1277                 sc->mdt[ch][i].status = 0;
1278                 sc->mdt[ch][i].m = NULL;
1279                 sc->mdt[ch][i].data = 0;
1280
1281                 MGETHDR(m, MB_WAIT, MT_DATA);
1282                 if (m == NULL)
1283                         goto errfree;
1284                 MCLGET(m, MB_WAIT);
1285                 if ((m->m_flags & M_EXT) == 0) {
1286                         /* We've waited mbuf_wait and still got nothing.
1287                            We're calling with MB_TRYWAIT anyway - a little
1288                            defensive programming costs us very little - if
1289                            anything at all in the case of error. */
1290                         m_free(m);
1291                         goto errfree;
1292                 }
1293                 sc->mdr[ch][i].m = m;
1294                 sc->mdr[ch][i].data = vtophys(m->m_data);
1295                 sc->mdr[ch][i].status = 1600; /* MTU */
1296         }
1297         sch->tx_last_md = sch->tx_next_md = &sc->mdt[ch][0];
1298
1299         /* Configure it into the chip */
1300         sc->ram->thp[ch] = vtophys(&sc->mdt[ch][0]);
1301         sc->ram->tmp[ch] = vtophys(&sc->mdt[ch][0]);
1302         sc->ram->rhp[ch] = vtophys(&sc->mdr[ch][0]);
1303         sc->ram->rmp[ch] = vtophys(&sc->mdr[ch][0]);
1304
1305         /* Activate the Channel */
1306         sc->reg->srd = sc->last = 0x0800 + ch;
1307         tsleep(&sc->last, PCATCH, "con4", hz);
1308         sc->reg->srd = sc->last = 0x0820 + ch;
1309         tsleep(&sc->last, PCATCH, "con3", hz);
1310
1311         return (0);
1312
1313 errfree:
1314         while (i > 0) {
1315                 /* Don't leak all the previously allocated mbufs in this loop */
1316                 i--;
1317                 m_free(sc->mdr[ch][i].m);
1318         }
1319         kfree(sc->mdt[ch], M_MUSYCC);
1320         kfree(sc->mdr[ch], M_MUSYCC);
1321         return (ENOBUFS);
1322 }
1323
1324 static int
1325 musycc_disconnect(hook_p hook)
1326 {
1327         struct softc *sc;
1328         struct csoftc *csc;
1329         struct schan *sch;
1330         int i, ch;
1331
1332         sch = hook->private;
1333         sc = sch->sc;
1334         csc = sc->csc;
1335         ch = sch->chan;
1336
1337         while (csc->state != C_RUNNING)
1338                 tsleep(&csc->state, PCATCH, "crun", hz/10);
1339
1340         /* Deactivate the channel */
1341         sc->reg->srd = sc->last = 0x0900 + sch->chan;
1342         tsleep(&sc->last, PCATCH, "con3", hz);
1343         sc->reg->srd = sc->last = 0x0920 + sch->chan;
1344         tsleep(&sc->last, PCATCH, "con4", hz);
1345
1346         if (sch->state == DOWN)
1347                 return (0);
1348         sch->state = DOWN;
1349
1350         sc->ram->thp[ch] = 0;
1351         sc->ram->tmp[ch] = 0;
1352         sc->ram->rhp[ch] = 0;
1353         sc->ram->rmp[ch] = 0;
1354         for (i = 0; i < sch->nmd; i++) {
1355                 if (sc->mdt[ch][i].m != NULL)
1356                         m_freem(sc->mdt[ch][i].m);
1357                 if (sc->mdr[ch][i].m != NULL)
1358                         m_freem(sc->mdr[ch][i].m);
1359         }
1360         kfree(sc->mdt[ch], M_MUSYCC);
1361         sc->mdt[ch] = NULL;
1362         kfree(sc->mdr[ch], M_MUSYCC);
1363         sc->mdr[ch] = NULL;
1364
1365         for (i = 0; i < 32; i++) {
1366                 if (sch->ts & (1 << i)) {
1367                         sc->ram->rtsm[i] = 0;
1368                         sc->ram->ttsm[i] = 0;
1369                 }
1370         }
1371         sc->nhooks--;
1372         sch->tx_pending = 0;
1373
1374         return (0);
1375 }
1376
1377
1378
1379 /*
1380  * PCI initialization stuff
1381  */
1382
1383 static int
1384 musycc_probe(device_t self)
1385 {
1386         char desc[40];
1387
1388         if (sizeof(struct groupr) != 1572) {
1389                 kprintf("sizeof(struct groupr) = %d, should be 1572\n",
1390                     sizeof(struct groupr));
1391                 return(ENXIO);
1392         }
1393
1394         if (sizeof(struct globalr) != 1572) {
1395                 kprintf("sizeof(struct globalr) = %d, should be 1572\n",
1396                     sizeof(struct globalr));
1397                 return(ENXIO);
1398         }
1399
1400         if (sizeof(struct mycg) > 2048) {
1401                 kprintf("sizeof(struct mycg) = %d, should be <= 2048\n",
1402                     sizeof(struct mycg));
1403                 return(ENXIO);
1404         }
1405
1406         switch (pci_get_devid(self)) {
1407         case 0x8471109e: strcpy(desc, "CN8471 MUSYCC"); break;
1408         case 0x8472109e: strcpy(desc, "CN8472 MUSYCC"); break;
1409         case 0x8474109e: strcpy(desc, "CN8474 MUSYCC"); break;
1410         case 0x8478109e: strcpy(desc, "CN8478 MUSYCC"); break;
1411         default:
1412                 return (ENXIO);
1413         }
1414
1415         switch (pci_get_function(self)) {
1416         case 0: strcat(desc, " Network controller"); break;
1417         case 1: strcat(desc, " Ebus bridge"); break;
1418         default:
1419                 return (ENXIO);
1420         }
1421
1422         device_set_desc_copy(self, desc);
1423         return 0;
1424 }
1425
1426 static int
1427 musycc_attach(device_t self)
1428 {
1429         struct csoftc *csc;
1430         struct resource *res;
1431         struct softc *sc;
1432         int rid, i, error;
1433         int f;
1434         u_int32_t       *u32p, u;
1435         static int once;
1436
1437         if (!once) {
1438                 once++;
1439                 error = ng_newtype(&ngtypestruct);
1440                 if (error != 0) 
1441                         kprintf("ng_newtype() failed %d\n", error);
1442         }
1443         kprintf("We have %d pad bytes in mycg\n", 2048 - sizeof(struct mycg));
1444
1445         f = pci_get_function(self);
1446         /* For function zero allocate a csoftc */
1447         if (f == 0) {
1448                 csc = kmalloc(sizeof(*csc), M_MUSYCC, M_WAITOK | M_ZERO);
1449                 csc->bus = pci_get_bus(self);
1450                 csc->slot = pci_get_slot(self);
1451                 LIST_INSERT_HEAD(&sc_list, csc, list);
1452         } else {
1453                 LIST_FOREACH(csc, &sc_list, list) {
1454                         if (csc->bus != pci_get_bus(self))
1455                                 continue;
1456                         if (csc->slot != pci_get_slot(self))
1457                                 continue;
1458                         break;
1459                 }
1460         }
1461         csc->f[f] = self;
1462         device_set_softc(self, csc);
1463         rid = PCIR_MAPS;
1464         res = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
1465             0, ~0, 1, RF_ACTIVE);
1466         if (res == NULL) {
1467                 device_printf(self, "Could not map memory\n");
1468                 return ENXIO;
1469         }
1470         csc->virbase[f] = (u_char *)rman_get_virtual(res);
1471         csc->physbase[f] = rman_get_start(res);
1472
1473         /* Allocate interrupt */
1474         rid = 0;
1475         csc->irq[f] = bus_alloc_resource(self, SYS_RES_IRQ, &rid, 0, ~0,
1476             1, RF_SHAREABLE | RF_ACTIVE);
1477
1478         if (csc->irq[f] == NULL) {
1479                 kprintf("couldn't map interrupt\n");
1480                 return(ENXIO);
1481         }
1482
1483         error = bus_setup_intr(self, csc->irq[f], 0,
1484                                (f == 0 ? musycc_intr0 : musycc_intr1), csc,
1485                                &csc->intrhand[f], NULL);
1486
1487         if (error) {
1488                 kprintf("couldn't set up irq\n");
1489                 return(ENXIO);
1490         }
1491
1492         if (f == 0)
1493                 return (0);
1494
1495         for (i = 0; i < 2; i++)
1496                 kprintf("f%d: device %p virtual %p physical %08x\n",
1497                     i, csc->f[i], csc->virbase[i], csc->physbase[i]);
1498
1499         csc->reg = (struct globalr *)csc->virbase[0];
1500         csc->reg->glcd = 0x3f30;        /* XXX: designer magic */
1501         u32p = (u_int32_t *)csc->virbase[1];
1502         u = u32p[0x1200];
1503         if ((u & 0xffff0000) != 0x13760000) {
1504                 kprintf("Not a LMC1504 (ID is 0x%08x).  Bailing out.\n", u);
1505                 return(ENXIO);
1506         }
1507         csc->nchan = (u >> 8) & 0xf;
1508         kprintf("Found <LanMedia LMC1504 Rev %d Chan %d>\n", (u >> 12) & 0xf, csc->nchan);
1509
1510         csc->creg = 0xfe;
1511         csc->cregp = &u32p[0x1000];
1512         *csc->cregp = csc->creg;        
1513         for (i = 0; i < csc->nchan; i++) {
1514                 sc = &csc->serial[i];
1515                 sc->csc = csc;
1516                 sc->last = 0xffffffff;
1517                 sc->ds8370 = (u_int32_t *)
1518                     (csc->virbase[1] + i * 0x800);
1519                 sc->ds847x = csc->virbase[0] + i * 0x800;
1520                 sc->reg = (struct globalr *)
1521                     (csc->virbase[0] + i * 0x800);
1522                 sc->mycg = kmalloc(sizeof(struct mycg), M_MUSYCC,
1523                                    M_WAITOK | M_ZERO);
1524                 sc->ram = &sc->mycg->cg;
1525
1526                 error = ng_make_node_common(&ngtypestruct, &sc->node);
1527                 if (error) {
1528                         kprintf("ng_make_node_common() failed %d\n", error);
1529                         continue;
1530                 }       
1531                 sc->node->private = sc;
1532                 ksprintf(sc->nodename, "sync-%d-%d-%d",
1533                         csc->bus,
1534                         csc->slot,
1535                         i);
1536                 error = ng_name_node(sc->node, sc->nodename);
1537                 /* XXX Apparently failure isn't a problem */
1538         }
1539         csc->ram = (struct globalr *)&csc->serial[0].mycg->cg;
1540         sc = &csc->serial[0];
1541         sc->reg->srd = sc->last = 0x100;
1542         csc->state = C_IDLE;
1543
1544         return 0;
1545 }
1546
1547 static device_method_t musycc_methods[] = {
1548         /* Device interface */
1549         DEVMETHOD(device_probe,         musycc_probe),
1550         DEVMETHOD(device_attach,        musycc_attach),
1551         DEVMETHOD(device_suspend,       bus_generic_suspend),
1552         DEVMETHOD(device_resume,        bus_generic_resume),
1553         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
1554
1555         {0, 0}
1556 };
1557  
1558 static driver_t musycc_driver = {
1559         "musycc",
1560         musycc_methods,
1561         0
1562 };
1563
1564 DRIVER_MODULE(musycc, pci, musycc_driver, musycc_devclass, NULL, NULL);
1565