diff --git a/sys/dev/musycc/musycc.c b/sys/dev/musycc/musycc.c deleted file mode 100644 index d9503f915815..000000000000 --- a/sys/dev/musycc/musycc.c +++ /dev/null @@ -1,1567 +0,0 @@ -/*- - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * Card state machine: - * ------------------- - * - * This is the state engine which drives the card "as such" which in reality - * means the MUSYCC chip. - * - * State Description - * - * IDLE The card is in this state when no channels are configured. - * This is the state we leave the card in after _attach() - * - * INIT The card is being initialized - * - * RUNNING The card is running - * - * FAULT The card is hosed and being reset - * - * ------------------ - * / \ - * v | - * IDLE ---> INIT ---> RUNNING - * ^ | - * | | - * | v - * FAULT - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pci_if.h" - - -#include -#include - -#include -#include - -static MALLOC_DEFINE(M_MUSYCC, "musycc", "MUSYCC related"); - -static int maxlatency = 250; -SYSCTL_INT(_debug, OID_AUTO, musycc_maxlatency, CTLFLAG_RW, &maxlatency, 0, - "The number of milliseconds a packet is allowed to spend in the output queue. " - "If the output queue is longer than this number of milliseconds when the packet " - "arrives for output, the packet will be dropped." -); - -static int debug = 0; -SYSCTL_INT(_debug, OID_AUTO, musycc_debug, CTLFLAG_RW, &debug, 0, ""); - -struct softc; -static void init_8370(struct softc *sc); -static u_int32_t parse_ts(const char *s, int *nbit); - -/* - * Device driver initialization stuff - */ - -static devclass_t musycc_devclass; - -/* XXX: Notice, these babies must be aligned to 2k boundaries [5-7] */ -struct groupr { - u_int32_t thp[32]; /* Transmit Head Pointer [5-29] */ - u_int32_t tmp[32]; /* Transmit Message Pointer [5-30] */ - u_int32_t rhp[32]; /* Receive Head Pointer [5-29] */ - u_int32_t rmp[32]; /* Receive Message Pointer [5-30] */ - u_int8_t ttsm[128]; /* Time Slot Map [5-22] */ - u_int8_t tscm[256]; /* Subchannel Map [5-24] */ - u_int32_t tcct[32]; /* Channel Configuration [5-26] */ - u_int8_t rtsm[128]; /* Time Slot Map [5-22] */ - u_int8_t rscm[256]; /* Subchannel Map [5-24] */ - u_int32_t rcct[32]; /* Channel Configuration [5-26] */ - u_int32_t __glcd; /* Global Configuration Descriptor [5-10] */ - u_int32_t __iqp; /* Interrupt Queue Pointer [5-36] */ - u_int32_t __iql; /* Interrupt Queue Length [5-36] */ - u_int32_t grcd; /* Group Configuration Descriptor [5-16] */ - u_int32_t mpd; /* Memory Protection Descriptor [5-18] */ - u_int32_t mld; /* Message Length Descriptor [5-20] */ - u_int32_t pcd; /* Port Configuration Descriptor [5-19] */ - u_int32_t __rbist; /* Receive BIST status [5-4] */ - u_int32_t __tbist; /* Receive BIST status [5-4] */ -}; - -struct globalr { - u_int32_t gbp; /* Group Base Pointer */ - u_int32_t dacbp; /* Dual Address Cycle Base Pointer */ - u_int32_t srd; /* Service Request Descriptor */ - u_int32_t isd; /* Interrupt Service Descriptor */ - u_int32_t __thp[28]; /* Transmit Head Pointer [5-29] */ - u_int32_t __tmp[32]; /* Transmit Message Pointer [5-30] */ - u_int32_t __rhp[32]; /* Receive Head Pointer [5-29] */ - u_int32_t __rmp[32]; /* Receive Message Pointer [5-30] */ - u_int8_t ttsm[128]; /* Time Slot Map [5-22] */ - u_int8_t tscm[256]; /* Subchannel Map [5-24] */ - u_int32_t tcct[32]; /* Channel Configuration [5-26] */ - u_int8_t rtsm[128]; /* Time Slot Map [5-22] */ - u_int8_t rscm[256]; /* Subchannel Map [5-24] */ - u_int32_t rcct[32]; /* Channel Configuration [5-26] */ - u_int32_t glcd; /* Global Configuration Descriptor [5-10] */ - u_int32_t iqp; /* Interrupt Queue Pointer [5-36] */ - u_int32_t iql; /* Interrupt Queue Length [5-36] */ - u_int32_t grcd; /* Group Configuration Descriptor [5-16] */ - u_int32_t mpd; /* Memory Protection Descriptor [5-18] */ - u_int32_t mld; /* Message Length Descriptor [5-20] */ - u_int32_t pcd; /* Port Configuration Descriptor [5-19] */ - u_int32_t rbist; /* Receive BIST status [5-4] */ - u_int32_t tbist; /* Receive BIST status [5-4] */ -}; - -/* - * Because the chan_group must be 2k aligned we create this super - * structure so we can use the remaining 476 bytes for something useful - */ - -struct mycg { - struct groupr cg; -}; - -struct mdesc { - u_int32_t status; - u_int32_t data; - u_int32_t next; - /* Software only */ - struct mbuf *m; - struct mdesc *snext; -}; - -#define NPORT 8 - -#define NHDLC 32 - -#define NIQD 32 - -struct softc; - -struct schan { - enum {DOWN, UP} state; - struct softc *sc; - int chan; - u_int32_t ts; - char hookname[8]; - - hook_p hook; - - u_long rx_drop; /* mbuf allocation failures */ - u_long tx_limit; - u_long tx_pending; - struct mdesc *tx_next_md; /* next MD */ - struct mdesc *tx_last_md; /* last MD */ - int rx_last_md; /* index to next MD */ - int nmd; /* count of MD's. */ - - time_t last_recv; - time_t last_rdrop; - time_t last_rxerr; - u_long crc_error; - u_long dribble_error; - u_long long_error; - u_long abort_error; - u_long short_error; - u_long txn, rxn; - - time_t last_xmit; - time_t last_txerr; - - time_t last_txdrop; - u_long tx_drop; - -#if 0 - - - u_long rx_error; - - u_long overflow_error; - - int last_error; - int prev_error; - -#endif -}; - -enum framing {WHOKNOWS, E1, E1U, T1, T1U}; -enum clocksource {EXT, INT}; - -struct softc { - enum framing framing; - enum clocksource clocksource; - int nhooks; - u_int32_t last; - struct csoftc *csc; - u_int32_t *ds8370; - void *ds847x; - struct globalr *reg; - struct groupr *ram; - struct mycg *mycg; - struct mdesc *mdt[NHDLC]; - struct mdesc *mdr[NHDLC]; - node_p node; /* NG node */ - char nodename[NG_NODESIZ]; /* NG nodename */ - struct schan *chan[NHDLC]; - u_long cnt_ferr; - u_long cnt_cerr; - u_long cnt_lcv; - u_long cnt_febe; - u_long cnt_berr; - u_long cnt_fred; - u_long cnt_cofa; - u_long cnt_sef; -}; - -/* - * SoftC for the entire card. - */ - -struct csoftc { - enum { C_IDLE, C_INIT, C_RUNNING, C_FAULT } state; - - int unit, bus, slot; - LIST_ENTRY(csoftc) list; - - device_t f[2]; - struct resource *irq[2]; - void *intrhand[2]; - vm_offset_t physbase[2]; - u_char *virbase[2]; - - u_int creg, *cregp; - int nchan; - struct softc serial[NPORT]; - - struct globalr *reg; - struct globalr *ram; - u_int32_t iqd[NIQD]; -}; - -/* - * - */ - -#define NG_NODETYPE "lmc1504" - -static ng_constructor_t musycc_constructor; -static ng_rcvmsg_t musycc_rcvmsg; -static ng_shutdown_t musycc_shutdown; -static ng_newhook_t musycc_newhook; -static ng_connect_t musycc_connect; -static ng_rcvdata_t musycc_rcvdata; -static ng_disconnect_t musycc_disconnect; - -static struct ng_type ngtypestruct = { - .version = NG_ABI_VERSION, - .name = NG_NODETYPE, - .constructor = musycc_constructor, - .rcvmsg = musycc_rcvmsg, - .shutdown = musycc_shutdown, - .newhook = musycc_newhook, - .connect = musycc_connect, - .rcvdata = musycc_rcvdata, - .disconnect = musycc_disconnect, -}; - -/* - * - */ - -static u_int32_t -parse_ts(const char *s, int *nbit) -{ - unsigned r; - int i, j; - char *p; - - r = 0; - j = -1; - *nbit = 0; - while(*s) { - i = strtol(s, &p, 0); - if (i < 0 || i > 31) - return (0); - while (j != -1 && j < i) { - r |= 1 << j++; - (*nbit)++; - } - j = -1; - r |= 1 << i; - (*nbit)++; - if (*p == ',') { - s = p + 1; - continue; - } else if (*p == '-') { - j = i + 1; - s = p + 1; - continue; - } else if (!*p) { - break; - } else { - return (0); - } - } - return (r); -} - -/* - * - */ - - -static LIST_HEAD(, csoftc) sc_list = LIST_HEAD_INITIALIZER(&sc_list); - -static void -poke_847x(void *dummy) -{ - int i; - struct csoftc *csc; - - timeout(poke_847x, NULL, 1); - LIST_FOREACH(csc, &sc_list, list) { - i = (csc->creg >> 24 & 0xf); - csc->creg &= ~0xf000000; - i++; - csc->creg |= (i & 0xf) << 24; - *csc->cregp = csc->creg; -#if 0 - for (i = 0; i < sc->nchan; i++) { - if (sc->serial[i].last == 0xffffffff) { - sc->serial[i].reg->srd = 0; - sc->serial[i].last = 0; - return; - } - } -#endif - } -} - -static void -init_card(struct csoftc *csc) -{ - - printf("init_card(%p)\n", csc); - - csc->state = C_INIT; - csc->reg->srd = 0x100; - tsleep(csc, PZERO | PCATCH, "icard", hz / 10); - csc->reg->gbp = vtophys(csc->ram); - csc->ram->glcd = 0x3f30; /* XXX: designer magic */ - - csc->ram->iqp = vtophys(csc->iqd); - csc->ram->iql = NIQD - 1; - csc->ram->dacbp = 0; /* 32bit only */ - - csc->reg->srd = csc->serial[0].last = 0x400; - tsleep(&csc->serial[0].last, PZERO | PCATCH, "con1", hz); - timeout(poke_847x, NULL, 1); - csc->state = C_RUNNING; -} - -static void -init_ctrl(struct softc *sc) -{ - int i; - - printf("init_ctrl(%p) [%s] [%08x]\n", sc, sc->nodename, sc->csc->reg->glcd); - init_8370(sc); - tsleep(sc, PZERO | PCATCH, "ds8370", hz); - printf("%s: glcd: [%08x]\n", sc->nodename, sc->csc->reg->glcd); - sc->reg->gbp = vtophys(sc->ram); - sc->ram->grcd = 0x00000001; /* RXENBL */ - sc->ram->grcd |= 0x00000002; /* TXENBL */ - sc->ram->grcd |= 0x00000004; /* SUBDSBL */ - if (sc->framing == E1 || sc->framing == T1) - sc->ram->grcd |= 0x00000008; /* OOFABT */ - else - sc->ram->grcd |= 0x00000000; /* !OOFABT */ - - sc->ram->grcd |= 0x00000020; /* MSKCOFA */ - - sc->ram->grcd |= 0x00000440; /* POLLTH=1 */ - - sc->ram->mpd = 0; /* Memory Protection NI [5-18] */ - - sc->ram->pcd = 0x0000001; /* PORTMD=1 (E1/32ts) */ - sc->ram->pcd |= 1 << 5; /* TSYNC_EDGE */ - sc->ram->pcd |= 1 << 9; /* TRITX */ - - /* Message length descriptor */ - /* XXX: MTU */ - sc->ram->mld = 1600; - sc->ram->mld |= (1600 << 16); - - for (i = 0; i < NHDLC; i++) { - sc->ram->ttsm[i] = 0; - sc->ram->rtsm[i] = 0; - } - sc->reg->srd = sc->last = 0x500; - tsleep(&sc->last, PZERO | PCATCH, "con1", hz); - sc->reg->srd = sc->last = 0x520; - tsleep(&sc->last, PZERO | PCATCH, "con1", hz); -} - -/* - * - */ - -static void -status_chans(struct softc *sc, char *s) -{ - int i; - struct schan *scp; - - s += strlen(s); - for (i = 0; i < NHDLC; i++) { - scp = sc->chan[i]; - if (scp == NULL) - continue; - sprintf(s + strlen(s), "c%2d:", i); - sprintf(s + strlen(s), " ts %08x", scp->ts); - sprintf(s + strlen(s), " RX %lus/%lus", - (long)(time_second - scp->last_recv), - (long)(time_second - scp->last_rxerr)); - sprintf(s + strlen(s), " TX %lus/%lus/%lus", - (long)(time_second - scp->last_xmit), - (long)(time_second - scp->last_txerr), - (long)(time_second - scp->last_txdrop)); - sprintf(s + strlen(s), " TXdrop %lu Pend %lu", - scp->tx_drop, - scp->tx_pending); - sprintf(s + strlen(s), " CRC %lu Dribble %lu Long %lu Short %lu Abort %lu", - scp->crc_error, - scp->dribble_error, - scp->long_error, - scp->short_error, - scp->abort_error); - sprintf(s + strlen(s), "\n TX: %lu RX: %lu\n", - scp->txn, scp->rxn); - } -} - - -/* - * - */ - -static void -status_8370(struct softc *sc, char *s) -{ - u_int32_t *p = sc->ds8370; - - s += strlen(s); - sprintf(s, "Framer: "); s += strlen(s); - switch (sc->framing) { - case WHOKNOWS: sprintf(s, "(unconfigured)\n"); break; - case E1: sprintf(s, "(e1)\n"); break; - case E1U: sprintf(s, "(e1u)\n"); break; - case T1: sprintf(s, "(t1)\n"); break; - case T1U: sprintf(s, "(t1u)\n"); break; - default: sprintf(s, "(mode %d XXX?)\n", sc->framing); break; - } - s += strlen(s); - sprintf(s, " Red alarms:"); s += strlen(s); - if (p[0x47] & 0x08) { sprintf(s, " ALOS"); s += strlen(s); } - if (p[0x47] & 0x04) { sprintf(s, " LOS"); s += strlen(s); } - if (sc->framing == E1 || sc->framing == T1) { - if (p[0x47] & 0x02) { sprintf(s, " LOF"); s += strlen(s); } - } - sprintf(s, "\n Yellow alarms:"); s += strlen(s); - if (p[0x47] & 0x80) { sprintf(s, " RMYEL"); s += strlen(s); } - if (p[0x47] & 0x40) { sprintf(s, " RYEL"); s += strlen(s); } - sprintf(s, "\n Blue alarms:"); s += strlen(s); - if (p[0x47] & 0x10) { sprintf(s, " AIS"); s += strlen(s); } - sprintf(s, "\n"); s += strlen(s); - sprintf(s, "\n Various alarms:"); s += strlen(s); - if (p[0x48] & 0x10) { sprintf(s, " TSHORT"); s += strlen(s); } - sprintf(s, "\n Counters:"); s += strlen(s); - if (sc->framing == E1) { - sprintf(s, " FERR=%lu", sc->cnt_ferr); s += strlen(s); - } - sprintf(s, " CERR=%lu", sc->cnt_cerr); s += strlen(s); - sprintf(s, " LCV=%lu", sc->cnt_lcv); s += strlen(s); - sprintf(s, " FEBE=%lu", sc->cnt_febe); s += strlen(s); - sprintf(s, " BERR=%lu", sc->cnt_berr); s += strlen(s); - sprintf(s, " FRED=%lu", sc->cnt_fred); s += strlen(s); - sprintf(s, " COFA=%lu", sc->cnt_cofa); s += strlen(s); - sprintf(s, " SEF=%lu", sc->cnt_sef); s += strlen(s); - sprintf(s, "\n"); s += strlen(s); -} - -static void -dump_8370(struct softc *sc, char *s, int offset) -{ - int i, j; - u_int32_t *p = sc->ds8370; - - s += strlen(s); - for (i = 0; i < 0x100; i += 16) { - sprintf(s, "%03x: ", i + offset); - s += strlen(s); - for (j = 0; j < 0x10; j ++) { - sprintf(s, " %02x", p[i + j + offset] & 0xff); - s += strlen(s); - } - sprintf(s, "\n"); - s += strlen(s); - } -} - -static void -init_8370(struct softc *sc) -{ - int i; - u_int32_t *p = sc->ds8370; - - p[0x001] = 0x80; /* CR0 - Reset */ - DELAY(20); - p[0x001] = 0x00; /* CR0 - E1, RFRAME: FAS only */ - DELAY(20); - if (sc->clocksource == INT) - p[0x002] = 0x40; /* JAT_CR - XXX */ - else - p[0x002] = 0x20; /* JAT_CR - XXX */ - p[0x00D] = 0x01; /* IER6 - ONESEC */ - p[0x014] = 0x00; /* LOOP - */ - p[0x015] = 0x00; /* DL3_TS - */ - p[0x016] = 0x00; /* DL3_BIT - */ - p[0x017] = 0x00; /* DL3_BIT - */ - p[0x018] = 0xFF; /* PIO - XXX */ - p[0x019] = 0x3c; /* POE - CLADO_OE|RCKO_OE */ - if (sc->clocksource == INT) - p[0x01A] = 0x37; /* CMUX - RSBCKI(RSBCKI), TSBCKI(CLADO), CLADO(RCKO), TCKI(CLADO) */ - else - p[0x01A] = 0x37; /* CMUX - RSBCKI(RSBCKI), TSBCKI(RSBCKI), CLADO(RCKO), TCKI(RCKO) */ - - /* I.431/G.775 */ - p[0x020] = 0x41; /* LIU_CR - SQUELCH */ - p[0x022] = 0xb1; /* RLIU_CR - */ - p[0x024] = 0x1d; /* VGA_MAX - */ - p[0x027] = 0xba; /* DSLICE - */ - p[0x028] = 0xda; /* EQ_OUT - */ - p[0x02a] = 0xa6; /* PRE_EQ - */ - - if (sc->framing == E1U || sc->framing == T1U) - p[0x040] = 0x49; /* RCRO - XXX */ - else - p[0x040] = 0x09; /* RCRO - XXX */ - - p[0x041] = 0x00; /* RPATT - XXX */ - p[0x045] = 0x00; /* RALM - XXX */ - p[0x046] = 0x05; /* LATCH - LATCH_CNT|LATCH_ALM */ - - p[0x068] = 0x4c; /* TLIU_CR - TERM|Pulse=6 */ - p[0x070] = 0x04; /* TCR0 - TFRAME=4 */ - - if (sc->framing == E1U || sc->framing == T1U) - p[0x071] = 0x41; /* TCR1 - TZCS */ - else - p[0x071] = 0x51; /* TCR1 - TZCS */ - - if (sc->framing == E1U || sc->framing == T1U) - p[0x072] = 0x00; - else - p[0x072] = 0x1b; /* TCR1 - INS_YEL|INS_MF|INS_CRC|INS_FBIT */ - - p[0x073] = 0x00; /* TERROR */ - p[0x074] = 0x00; /* TMAN */ - - if (sc->framing == E1U || sc->framing == T1U) - p[0x075] = 0x0; /* TALM */ - else - p[0x075] = 0x10; /* TALM - AUTO_YEL */ - - p[0x076] = 0x00; /* TPATT */ - p[0x077] = 0x00; /* TLP */ - - p[0x090] = 0x05; /* CLAD_CR - XXX */ - p[0x091] = 0x01; /* CSEL - 2048kHz */ - - if (sc->framing == E1U || sc->framing == T1U) { - p[0x0a0] = 0x00; - p[0x0a6] = 0x00; - p[0x0b1] = 0x00; - } - - p[0x0d0] = 0x46; /* SBI_CR - SBI=6 */ - p[0x0d1] = 0x70; /* RSB_CR - XXX */ - p[0x0d2] = 0x00; /* RSYNC_BIT - 0 */ - p[0x0d3] = 0x00; /* RSYNC_TS - 0 */ - p[0x0d4] = 0x30; /* TSB_CR - XXX */ - p[0x0d5] = 0x00; /* TSYNC_BIT - 0 */ - p[0x0d6] = 0x00; /* TSYNC_TS - 0 */ - if (sc->framing == E1U || sc->framing == T1U) - p[0x0d7] = 0x05; /* RSIG_CR - 0 | FRZ_OFF*/ - else - p[0x0d7] = 0x01; /* RSIG_CR - 0 */ - p[0x0d8] = 0x00; /* RSIG_FRM - 0 */ - for (i = 0; i < 32; i ++) { - p[0x0e0 + i] = 0x0d; /* SBC$i - RINDO|TINDO|ASSIGN */ - p[0x100 + i] = 0x00; /* TPC$i - 0 */ - p[0x180 + i] = 0x00; /* RPC$i - 0 */ - } -} - -/* - * Interrupts - */ - -static void -musycc_intr0_tx_eom(struct softc *sc, int ch) -{ - struct schan *sch; - struct mdesc *md; - - sch = sc->chan[ch]; - if (sch == NULL || sch->state != UP) { - /* XXX: this should not happen once the driver is done */ - printf("Xmit packet on uninitialized channel %d\n", ch); - } - if (sc->mdt[ch] == NULL) - return; /* XXX: can this happen ? */ - for (;;) { - md = sch->tx_last_md; - if (md->status == 0) - break; - if (md->status & 0x80000000) - break; /* Not our mdesc, done */ - sch->tx_last_md = md->snext; - md->data = 0; - if (md->m != NULL) { - sch->tx_pending -= md->m->m_pkthdr.len; - m_freem(md->m); - md->m = NULL; - } - md->status = 0; - } -} - -/* - * Receive interrupt on controller *sc, channel ch - * - * We perambulate the Rx descriptor ring until we hit - * a mdesc which isn't ours to take. - */ - -static void -musycc_intr0_rx_eom(struct softc *sc, int ch) -{ - u_int32_t status, error; - struct schan *sch; - struct mbuf *m, *m2; - struct mdesc *md; - - sch = sc->chan[ch]; - if (sch == NULL || sch->state != UP) { - /* XXX: this should not happen once the driver is done */ - printf("Received packet on uninitialized channel %d\n", ch); - return; - } - if (sc->mdr[ch] == NULL) - return; /* XXX: can this happen ? */ - for (;;) { - md = &sc->mdr[ch][sch->rx_last_md]; - status = md->status; - if (!(status & 0x80000000)) - break; /* Not our mdesc, done */ - m = md->m; - m->m_len = m->m_pkthdr.len = status & 0x3fff; - error = (status >> 16) & 0xf; - if (error == 0) { - MGETHDR(m2, M_DONTWAIT, MT_DATA); - if (m2 != NULL) { - MCLGET(m2, M_DONTWAIT); - if((m2->m_flags & M_EXT) != 0) { - /* Substitute the mbuf+cluster. */ - md->m = m2; - md->data = vtophys(m2->m_data); - /* Pass the received mbuf upwards. */ - sch->last_recv = time_second; - NG_SEND_DATA_ONLY(error, sch->hook, m); - } else { - /* - * We didn't get a mbuf cluster, - * drop received packet, free the - * mbuf we cannot use and recycle - * the mbuf+cluster we already had. - */ - m_freem(m2); - sch->last_rdrop = time_second; - sch->rx_drop++; - } - } else { - /* - * We didn't get a mbuf, drop received packet - * and recycle the "old" mbuf+cluster. - */ - sch->last_rdrop = time_second; - sch->rx_drop++; - } - } else if (error == 9) { - sch->last_rxerr = time_second; - sch->crc_error++; - } else if (error == 10) { - sch->last_rxerr = time_second; - sch->dribble_error++; - } else if (error == 11) { - sch->last_rxerr = time_second; - sch->abort_error++; - } else if (error == 12) { - sch->last_rxerr = time_second; - sch->long_error++; - } else { - sch->last_rxerr = time_second; - /* Receive error, print some useful info */ - printf("%s %s: RX 0x%08x ", sch->sc->nodename, - sch->hookname, status); - /* Don't print a lot, just the begining will do */ - if (m->m_len > 16) - m->m_len = m->m_pkthdr.len = 16; - m_print(m, -1); - printf("\n"); - } - md->status = 1600; /* XXX: MTU */ - /* Check next mdesc in the ring */ - if (++sch->rx_last_md >= sch->nmd) - sch->rx_last_md = 0; - } -} - -static void -musycc_intr0(void *arg) -{ - int i, j, g, ch, ev, er; - struct csoftc *csc; - u_int32_t u, u1, n, c; - struct softc *sc; - - csc = arg; - - for (;;) { - u = csc->reg->isd; - c = u & 0x7fff; - n = u >> 16; - if (c == 0) - return; - if (debug & 1) - printf("%s: IRQ: %08x n = %d c = %d\n", csc->serial[0].nodename, u, n, c); - for (i = 0; i < c; i++) { - j = (n + i) % NIQD; - u1 = csc->iqd[j]; - g = (u1 >> 29) & 0x3; - g |= (u1 >> (14-2)) & 0x4; - ch = (u1 >> 24) & 0x1f; - ev = (u1 >> 20) & 0xf; - er = (u1 >> 16) & 0xf; - sc = &csc->serial[g]; - if (debug & 2) { - printf("%08x %d", u1, g); - printf("/%s", u1 & 0x80000000 ? "T" : "R"); - printf("/%02d", ch); - printf(" %02d", ev); - printf(":%02d", er); - printf("\n"); - } - switch (ev) { - case 1: /* SACK Service Request Acknowledge */ -#if 0 - printf("%s: SACK: %08x group=%d", sc->nodename, csc->iqd[j], g); - printf("/%s", csc->iqd[j] & 0x80000000 ? "T" : "R"); - printf(" cmd %08x (%08x) \n", sc->last, sc->reg->srd); -#endif - sc->last = 0xffffffff; - wakeup(&sc->last); - break; - case 5: /* CHABT Change To Abort Code (0x7e -> 0xff) */ - case 6: /* CHIC Change To Idle Code (0xff -> 0x7e) */ - break; - case 3: /* EOM End Of Message */ - if (csc->iqd[j] & 0x80000000) - musycc_intr0_tx_eom(sc, ch); - else - musycc_intr0_rx_eom(sc, ch); - break; - case 0: - if (er == 13) { /* SHT */ - sc->chan[ch]->last_rxerr = time_second; - sc->chan[ch]->short_error++; - break; - } - /* FALLTHROUGH */ - default: - musycc_intr0_tx_eom(sc, ch); - musycc_intr0_rx_eom(sc, ch); -#if 1 - printf("huh ? %08x %d", u1, g); - printf("/%s", u1 & 0x80000000 ? "T" : "R"); - printf("/%02d", ch); - printf(" %02d", ev); - printf(":%02d", er); - printf("\n"); -#endif - } - csc->iqd[j] = 0xffffffff; - j++; - j %= NIQD; - csc->reg->isd = j << 16; - } - } -} - -static void -musycc_intr1(void *arg) -{ - int i; - struct csoftc *csc; - struct softc *sc; - u_int32_t *u; - u_int8_t irr; - - csc = arg; - - for (i = 0; i < csc->nchan; i++) { - sc = &csc->serial[i]; - u = sc->ds8370; - irr = u[3]; - if (irr == 0) - continue; - if (u[0x5] & 1) { /* ONESEC */ - sc->cnt_ferr += u[0x50] & 0xff; - sc->cnt_ferr += (u[0x51] & 0xff) << 8; - sc->cnt_cerr += u[0x52] & 0xff; - sc->cnt_cerr += (u[0x53] & 0xff) << 8; - sc->cnt_lcv += u[0x54] & 0xff; - sc->cnt_lcv += (u[0x55] & 0xff) << 8; - sc->cnt_febe += u[0x56] & 0xff; - sc->cnt_febe += (u[0x57] & 0xff) << 8; - sc->cnt_berr += u[0x58] & 0xff; - sc->cnt_berr += (u[0x59] & 0xff) << 8; - sc->cnt_fred += (u[0x5a] & 0xf0) >> 4; - sc->cnt_cofa += (u[0x5a] & 0x0c) >> 2; - sc->cnt_sef += u[0x5a] & 0x03; - } - if (debug & 4) { - int j; - - printf("musycc_intr1:%d %02x", i, irr); - for (j = 4; j < 0x14; j++) - printf(" %02x", u[j] & 0xff); - printf("\n"); - } - } -} - -/* - * NetGraph Stuff - */ - -static int -musycc_constructor(node_p node) -{ - - return (EINVAL); -} - -static int -musycc_shutdown(node_p nodep) -{ - - return (EINVAL); -} - -static void -musycc_config(node_p node, char *set, char *ret) -{ - struct softc *sc; - struct csoftc *csc; - enum framing wframing; - int i; - - sc = NG_NODE_PRIVATE(node); - csc = sc->csc; - if (csc->state == C_IDLE) - init_card(csc); - while (csc->state != C_RUNNING) - tsleep(&csc->state, PZERO | PCATCH, "crun", hz/10); - if (set != NULL) { - if (!strncmp(set, "line ", 5)) { - wframing = sc->framing; - if (!strcmp(set, "line e1")) { - wframing = E1; - } else if (!strcmp(set, "line e1u")) { - wframing = E1U; - } else { - strcat(ret, "ENOGROK\n"); - return; - } - if (wframing == sc->framing) - return; - if (sc->nhooks > 0) { - sprintf(ret, "Cannot change line when %d hooks open\n", sc->nhooks); - return; - } - sc->framing = wframing; - init_ctrl(sc); - return; - } - if (!strcmp(set, "clock source internal")) { - sc->clocksource = INT; - init_ctrl(sc); - } else if (!strcmp(set, "clock source line")) { - sc->clocksource = EXT; - init_ctrl(sc); - } else if (!strcmp(set, "show 8370 0")) { - dump_8370(sc, ret, 0); - } else if (!strcmp(set, "show 8370 1")) { - dump_8370(sc, ret, 0x100); - } else if (!strncmp(set, "creg", 4)) { - i = strtol(set + 5, 0, 0); - printf("set creg %d\n", i); - csc->creg = 0xfe | (i << 24); - *csc->cregp = csc->creg; -/* - } else if (!strcmp(set, "reset")) { - reset_group(sc, ret); - } else if (!strcmp(set, "reset all")) { - reset_card(sc, ret); -*/ - } else { - printf("%s CONFIG SET [%s]\n", sc->nodename, set); - goto barf; - } - - return; - } - if (sc->framing == E1) - strcat(ret, "line e1\n"); - else if (sc->framing == E1U) - strcat(ret, "line e1u\n"); - if (sc->clocksource == INT) - strcat(ret, "clock source internal\n"); - else - strcat(ret, "clock source line\n"); - return; -barf: - strcpy(ret, "Syntax Error\n"); - strcat(ret, "\tline {e1|e1u}\n"); - strcat(ret, "\tshow 8370 {0|1}\n"); - return; -} - -/* - * Handle status and config enquiries. - * Respond with a synchronous response. - */ -static int -musycc_rcvmsg(node_p node, item_p item, hook_p lasthook) -{ - struct softc *sc; - struct ng_mesg *resp = NULL; - char *s, *r; - int error = 0; - struct ng_mesg *msg; - - - NGI_GET_MSG(item, msg); - sc = NG_NODE_PRIVATE(node); - if (msg->header.typecookie != NGM_GENERIC_COOKIE) - goto out; - - if (msg->header.cmd == NGM_TEXT_STATUS) { - NG_MKRESPONSE(resp, msg, - sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT); - if (resp == NULL) { - error = ENOMEM; - goto out; - } - s = (char *)resp->data; - status_8370(sc, s); - status_chans(sc,s); - resp->header.arglen = strlen(s) + 1; - NG_FREE_MSG(msg); - - } else if (msg->header.cmd == NGM_TEXT_CONFIG) { - if (msg->header.arglen) { - s = (char *)msg->data; - } else { - s = NULL; - } - - NG_MKRESPONSE(resp, msg, - sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT); - if (resp == NULL) { - error = ENOMEM; - goto out; - } - r = (char *)resp->data; - *r = '\0'; - musycc_config(node, s, r); - resp->header.arglen = strlen(r) + 1; - NG_FREE_MSG(msg); - } else { - error = EINVAL; - } - -out: - /* Take care of synchronous response, if any */ - NG_RESPOND_MSG(error, node, item, resp); - NG_FREE_MSG(msg); - return (error); -} - -static int -musycc_newhook(node_p node, hook_p hook, const char *name) -{ - struct softc *sc; - struct csoftc *csc; - struct schan *sch; - u_int32_t ts, chan; - int nbit; - - sc = NG_NODE_PRIVATE(node); - csc = sc->csc; - - while (csc->state != C_RUNNING) - tsleep(&csc->state, PZERO | PCATCH, "crun", hz/10); - - if (sc->framing == WHOKNOWS) - return (EINVAL); - - if (name[0] != 't' || name[1] != 's') - return (EINVAL); - ts = parse_ts(name + 2, &nbit); - if (ts == 0) - return (EINVAL); - chan = ffs(ts) - 1; - - if (sc->framing == E1U && nbit == 32) - ; - else if (sc->framing == T1U && nbit == 24) - ; - else if (ts & 1) - return (EINVAL); - - if (sc->chan[chan] == NULL) { - MALLOC(sch, struct schan *, sizeof(*sch), M_MUSYCC, M_WAITOK | M_ZERO); - sch->sc = sc; - sch->state = DOWN; - sch->chan = chan; - sprintf(sch->hookname, name); /* XXX overflow ? */ - sc->chan[chan] = sch; - } else if (sc->chan[chan]->state == UP) { - return (EBUSY); - } - sc->nhooks++; - sch = sc->chan[chan]; - sch->ts = ts; - sch->hook = hook; - sch->tx_limit = nbit * 8; - NG_HOOK_SET_PRIVATE(hook, sch); - return(0); -} - -static int -musycc_rcvdata(hook_p hook, item_p item) -{ - - struct softc *sc; - struct csoftc *csc; - struct schan *sch; - struct mdesc *md, *md0; - u_int32_t u, u0, len; - struct mbuf *m2; - struct mbuf *m; - - sch = NG_HOOK_PRIVATE(hook); - sc = sch->sc; - csc = sc->csc; - - if (csc->state != C_RUNNING) { - printf("csc->state = %d\n", csc->state); - NG_FREE_ITEM(item); - return (0); - } - - - if (sch->state != UP) { - printf("sch->state = %d\n", sch->state); - NG_FREE_ITEM(item); - return (0); - } - NGI_GET_M(item, m); - NG_FREE_ITEM(item); - if (sch->tx_pending + m->m_pkthdr.len > sch->tx_limit * maxlatency) { - sch->tx_drop++; - sch->last_txdrop = time_second; - NG_FREE_M(m); - return (0); - } - - /* find out if we have enough txmd's */ - m2 = m; - md = sch->tx_next_md; - for (len = m2->m_pkthdr.len; len; m2 = m2->m_next) { - if (m2->m_len == 0) - continue; - if (md->status != 0) { - sch->tx_drop++; - sch->last_txdrop = time_second; - NG_FREE_M(m); - return (0); - } - len -= m2->m_len; - md = md->snext; - } - - m2 = m; - md = md0 = sch->tx_next_md; - u0 = 0; - for (len = m->m_pkthdr.len; len > 0; m = m->m_next) { - if (m->m_len == 0) - continue; - if (md->status != 0) { - printf("Out of tx md(2)\n"); - sch->last_txerr = time_second; - sch->tx_drop++; - sch->last_txdrop = time_second; - NG_FREE_M(m); - break; - } - - md->data = vtophys(m->m_data); - if (md == md0) - u = 0x00000000; /* OWNER = CPU */ - else - u = 0x80000000; /* OWNER = MUSYCC */ - u |= m->m_len; - len -= m->m_len; - if (len > 0) { - md->m = NULL; - if (md == md0) - u0 = u; - else - md->status = u; - md = md->snext; - continue; - } - u |= 0x20000000; /* EOM */ - md->m = m2; - sch->tx_pending += m2->m_pkthdr.len; - if (md == md0) { - u |= 0x80000000; /* OWNER = MUSYCC */ - md->status = u; - } else { - md->status = u; - md0->status = u0 | 0x80000000; /* OWNER = MUSYCC */ - } - sch->last_xmit = time_second; - sch->tx_next_md = md->snext; - } - sch->txn++; - return (0); -} - -static int -musycc_connect(hook_p hook) -{ - struct softc *sc; - struct csoftc *csc; - struct schan *sch; - int nts, nbuf, i, nmd, ch; - struct mbuf *m; - - sch = NG_HOOK_PRIVATE(hook); - sc = sch->sc; - csc = sc->csc; - ch = sch->chan; - - while (csc->state != C_RUNNING) - tsleep(&csc->state, PZERO | PCATCH, "crun", hz/10); - - if (sch->state == UP) - return (0); - sch->state = UP; - - /* Setup the Time Slot Map */ - nts = 0; - for (i = ch; i < 32; i++) { - if (sch->ts & (1 << i)) { - sc->ram->rtsm[i] = ch | (4 << 5); - sc->ram->ttsm[i] = ch | (4 << 5); - nts++; - } - } - - /* - * Find the length of the first run of timeslots. - * XXX: find the longest instead. - */ - nbuf = 0; - for (i = ch; i < 32; i++) { - if (sch->ts & (1 << i)) - nbuf++; - else - break; - } - - printf("Connect ch= %d ts= %08x nts= %d nbuf = %d\n", - ch, sch->ts, nts, nbuf); - - /* Reread the Time Slot Map */ - sc->reg->srd = sc->last = 0x1800; - tsleep(&sc->last, PZERO | PCATCH, "con1", hz); - sc->reg->srd = sc->last = 0x1820; - tsleep(&sc->last, PZERO | PCATCH, "con2", hz); - - /* Set the channel mode */ - sc->ram->tcct[ch] = 0x2800; /* HDLC-FCS16 | MAXSEL[2] */ - sc->ram->rcct[ch] = 0x2800; /* HDLC-FCS16 | MAXSEL[2] */ - - /* - * Allocate the FIFO space - * We don't do subchanneling so we can use 128 dwords [4-13] - */ - sc->ram->tcct[ch] |= (1 + 2 * (nbuf - 1)) << 16; /* BUFFLEN */ - sc->ram->rcct[ch] |= (1 + 2 * (nbuf - 1)) << 16; /* BUFFLEN */ - sc->ram->tcct[ch] |= ((ch * 2) << 24); /* BUFFLOC */ - sc->ram->rcct[ch] |= ((ch * 2) << 24); /* BUFFLOC */ - - /* Reread the Channel Configuration Descriptor for this channel */ - sc->reg->srd = sc->last = 0x0b00 + ch; - tsleep(&sc->last, PZERO | PCATCH, "con3", hz); - sc->reg->srd = sc->last = 0x0b20 + ch; - tsleep(&sc->last, PZERO | PCATCH, "con4", hz); - - /* - * Figure out how many receive buffers we want: 10 + nts * 2 - * 1 timeslot, 50 bytes packets -> 68msec - * 31 timeslots, 50 bytes packets -> 14msec - */ - sch->nmd = nmd = 200 + nts * 4; - sch->rx_last_md = 0; - MALLOC(sc->mdt[ch], struct mdesc *, - sizeof(struct mdesc) * nmd, M_MUSYCC, M_WAITOK); - MALLOC(sc->mdr[ch], struct mdesc *, - sizeof(struct mdesc) * nmd, M_MUSYCC, M_WAITOK); - for (i = 0; i < nmd; i++) { - if (i == nmd - 1) { - sc->mdt[ch][i].snext = &sc->mdt[ch][0]; - sc->mdt[ch][i].next = vtophys(sc->mdt[ch][i].snext); - sc->mdr[ch][i].snext = &sc->mdr[ch][0]; - sc->mdr[ch][i].next = vtophys(sc->mdr[ch][i].snext); - } else { - sc->mdt[ch][i].snext = &sc->mdt[ch][i + 1]; - sc->mdt[ch][i].next = vtophys(sc->mdt[ch][i].snext); - sc->mdr[ch][i].snext = &sc->mdr[ch][i + 1]; - sc->mdr[ch][i].next = vtophys(sc->mdr[ch][i].snext); - } - sc->mdt[ch][i].status = 0; - sc->mdt[ch][i].m = NULL; - sc->mdt[ch][i].data = 0; - - MGETHDR(m, M_TRYWAIT, MT_DATA); - if (m == NULL) - goto errfree; - MCLGET(m, M_TRYWAIT); - if ((m->m_flags & M_EXT) == 0) { - /* We've waited mbuf_wait and still got nothing. - We're calling with M_TRYWAIT anyway - a little - defensive programming costs us very little - if - anything at all in the case of error. */ - m_free(m); - goto errfree; - } - sc->mdr[ch][i].m = m; - sc->mdr[ch][i].data = vtophys(m->m_data); - sc->mdr[ch][i].status = 1600; /* MTU */ - } - sch->tx_last_md = sch->tx_next_md = &sc->mdt[ch][0]; - - /* Configure it into the chip */ - sc->ram->thp[ch] = vtophys(&sc->mdt[ch][0]); - sc->ram->tmp[ch] = vtophys(&sc->mdt[ch][0]); - sc->ram->rhp[ch] = vtophys(&sc->mdr[ch][0]); - sc->ram->rmp[ch] = vtophys(&sc->mdr[ch][0]); - - /* Activate the Channel */ - sc->reg->srd = sc->last = 0x0800 + ch; - tsleep(&sc->last, PZERO | PCATCH, "con4", hz); - sc->reg->srd = sc->last = 0x0820 + ch; - tsleep(&sc->last, PZERO | PCATCH, "con3", hz); - NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook)); - - return (0); - -errfree: - while (i > 0) { - /* Don't leak all the previously allocated mbufs in this loop */ - i--; - m_free(sc->mdr[ch][i].m); - } - FREE(sc->mdt[ch], M_MUSYCC); - FREE(sc->mdr[ch], M_MUSYCC); - return (ENOBUFS); -} - -static int -musycc_disconnect(hook_p hook) -{ - struct softc *sc; - struct csoftc *csc; - struct schan *sch; - int i, ch; - - sch = NG_HOOK_PRIVATE(hook); - sc = sch->sc; - csc = sc->csc; - ch = sch->chan; - - while (csc->state != C_RUNNING) - tsleep(&csc->state, PZERO | PCATCH, "crun", hz/10); - - /* Deactivate the channel */ - sc->reg->srd = sc->last = 0x0900 + sch->chan; - tsleep(&sc->last, PZERO | PCATCH, "con3", hz); - sc->reg->srd = sc->last = 0x0920 + sch->chan; - tsleep(&sc->last, PZERO | PCATCH, "con4", hz); - - if (sch->state == DOWN) - return (0); - sch->state = DOWN; - - sc->ram->thp[ch] = 0; - sc->ram->tmp[ch] = 0; - sc->ram->rhp[ch] = 0; - sc->ram->rmp[ch] = 0; - for (i = 0; i < sch->nmd; i++) { - if (sc->mdt[ch][i].m != NULL) - m_freem(sc->mdt[ch][i].m); - if (sc->mdr[ch][i].m != NULL) - m_freem(sc->mdr[ch][i].m); - } - FREE(sc->mdt[ch], M_MUSYCC); - sc->mdt[ch] = NULL; - FREE(sc->mdr[ch], M_MUSYCC); - sc->mdr[ch] = NULL; - - for (i = 0; i < 32; i++) { - if (sch->ts & (1 << i)) { - sc->ram->rtsm[i] = 0; - sc->ram->ttsm[i] = 0; - } - } - sc->nhooks--; - sch->tx_pending = 0; - - return (0); -} - - - -/* - * PCI initialization stuff - */ - -static int -musycc_probe(device_t self) -{ - char desc[40]; - - if (sizeof(struct groupr) != 1572) { - printf("sizeof(struct groupr) = %zd, should be 1572\n", - sizeof(struct groupr)); - return(ENXIO); - } - - if (sizeof(struct globalr) != 1572) { - printf("sizeof(struct globalr) = %zd, should be 1572\n", - sizeof(struct globalr)); - return(ENXIO); - } - - if (sizeof(struct mycg) > 2048) { - printf("sizeof(struct mycg) = %zd, should be <= 2048\n", - sizeof(struct mycg)); - return(ENXIO); - } - - switch (pci_get_devid(self)) { - case 0x8471109e: strcpy(desc, "CN8471 MUSYCC"); break; - case 0x8472109e: strcpy(desc, "CN8472 MUSYCC"); break; - case 0x8474109e: strcpy(desc, "CN8474 MUSYCC"); break; - case 0x8478109e: strcpy(desc, "CN8478 MUSYCC"); break; - default: - return (ENXIO); - } - - switch (pci_get_function(self)) { - case 0: strcat(desc, " Network controller"); break; - case 1: strcat(desc, " Ebus bridge"); break; - default: - return (ENXIO); - } - - device_set_desc_copy(self, desc); - return BUS_PROBE_DEFAULT; -} - -static int -musycc_attach(device_t self) -{ - struct csoftc *csc; - struct resource *res; - struct softc *sc; - int rid, i, error; - int f; - u_int32_t *u32p, u; - static int once; - - if (!once) { - once++; - error = ng_newtype(&ngtypestruct); - if (error != 0) - printf("ng_newtype() failed %d\n", error); - } - printf("We have %zd pad bytes in mycg\n", 2048 - sizeof(struct mycg)); - - f = pci_get_function(self); - /* For function zero allocate a csoftc */ - if (f == 0) { - MALLOC(csc, struct csoftc *, sizeof(*csc), M_MUSYCC, M_WAITOK | M_ZERO); - csc->bus = pci_get_bus(self); - csc->slot = pci_get_slot(self); - LIST_INSERT_HEAD(&sc_list, csc, list); - } else { - LIST_FOREACH(csc, &sc_list, list) { - if (csc->bus != pci_get_bus(self)) - continue; - if (csc->slot != pci_get_slot(self)) - continue; - break; - } - } - csc->f[f] = self; - device_set_softc(self, csc); - rid = PCIR_BAR(0); - res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (res == NULL) { - device_printf(self, "Could not map memory\n"); - return ENXIO; - } - csc->virbase[f] = (u_char *)rman_get_virtual(res); - csc->physbase[f] = rman_get_start(res); - - /* Allocate interrupt */ - rid = 0; - csc->irq[f] = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); - - if (csc->irq[f] == NULL) { - printf("couldn't map interrupt\n"); - return(ENXIO); - } - - error = bus_setup_intr(self, csc->irq[f], INTR_TYPE_NET, - f == 0 ? musycc_intr0 : musycc_intr1, csc, &csc->intrhand[f]); - - if (error) { - printf("couldn't set up irq\n"); - return(ENXIO); - } - - if (f == 0) - return (0); - - for (i = 0; i < 2; i++) - printf("f%d: device %p virtual %p physical %08jx\n", - i, csc->f[i], csc->virbase[i], (uintmax_t)csc->physbase[i]); - - csc->reg = (struct globalr *)csc->virbase[0]; - csc->reg->glcd = 0x3f30; /* XXX: designer magic */ - u32p = (u_int32_t *)csc->virbase[1]; - u = u32p[0x1200]; - if ((u & 0xffff0000) != 0x13760000) { - printf("Not a LMC1504 (ID is 0x%08x). Bailing out.\n", u); - return(ENXIO); - } - csc->nchan = (u >> 8) & 0xf; - printf("Found \n", (u >> 12) & 0xf, csc->nchan); - - csc->creg = 0xfe; - csc->cregp = &u32p[0x1000]; - *csc->cregp = csc->creg; - for (i = 0; i < csc->nchan; i++) { - sc = &csc->serial[i]; - sc->csc = csc; - sc->last = 0xffffffff; - sc->ds8370 = (u_int32_t *) - (csc->virbase[1] + i * 0x800); - sc->ds847x = csc->virbase[0] + i * 0x800; - sc->reg = (struct globalr *) - (csc->virbase[0] + i * 0x800); - MALLOC(sc->mycg, struct mycg *, - sizeof(struct mycg), M_MUSYCC, M_WAITOK | M_ZERO); - sc->ram = &sc->mycg->cg; - - error = ng_make_node_common(&ngtypestruct, &sc->node); - if (error) { - printf("ng_make_node_common() failed %d\n", error); - continue; - } - NG_NODE_SET_PRIVATE(sc->node, sc); - sprintf(sc->nodename, "sync-%d-%d-%d", - csc->bus, - csc->slot, - i); - error = ng_name_node(sc->node, sc->nodename); - /* XXX Apparently failure isn't a problem */ - } - csc->ram = (struct globalr *)&csc->serial[0].mycg->cg; - sc = &csc->serial[0]; - sc->reg->srd = sc->last = 0x100; - csc->state = C_IDLE; - - return 0; -} - -static device_method_t musycc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, musycc_probe), - DEVMETHOD(device_attach, musycc_attach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - {0, 0} -}; - -static driver_t musycc_driver = { - "musycc", - musycc_methods, - 0 -}; - -DRIVER_MODULE(musycc, pci, musycc_driver, musycc_devclass, 0, 0); -