📄 si.c
字号:
} for (i=0; i < NSI; i++) { sc = &si_softc[i]; if ((caddr_t)sc->sc_paddr == (caddr_t)paddr) { DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: iomem (%x) already configured to si%d\n", id->id_unit, sc->sc_paddr, i)); return(0); } } /* Is there anything out there? (0x17 is just an arbitrary number) */ *maddr = 0x17; if (*maddr != 0x17) { DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: 0x17 check fail at phys 0x%x\n", id->id_unit, paddr));fail: return(0); } /* * Let's look first for a JET ISA card, since that's pretty easy * * All jet hosts are supposed to have this string in the IDROM, * but it's not worth checking on self-IDing busses like PCI. */ { unsigned char *jet_chk_str = "JET HOST BY KEV#"; for (i = 0; i < strlen(jet_chk_str); i++) if (jet_chk_str[i] != *(maddr + SIJETIDSTR + 2 * i)) goto try_mk2; } DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET first check - 0x%x\n", id->id_unit, (*(maddr+SIJETIDBASE)))); if (*(maddr+SIJETIDBASE) != (SISPLXID&0xff)) goto try_mk2; DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET second check - 0x%x\n", id->id_unit, (*(maddr+SIJETIDBASE+2)))); if (*(maddr+SIJETIDBASE+2) != ((SISPLXID&0xff00)>>8)) goto try_mk2; /* It must be a Jet ISA or RIO card */ DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET id check - 0x%x\n", id->id_unit, (*(maddr+SIUNIQID)))); if ((*(maddr+SIUNIQID) & 0xf0) !=0x20) goto try_mk2; /* It must be a Jet ISA SI/XIO card */ *(maddr + SIJETCONFIG) = 0; type = SIJETISA; ramsize = SIJET_RAMSIZE; goto got_card; /* * OK, now to see if whatever responded is really an SI card. * Try for a MK II next (SIHOST2) */try_mk2: for (i = SIPLSIG; i < SIPLSIG + 8; i++) if ((*(maddr+i) & 7) != (~(BYTE)i & 7)) goto try_mk1; /* It must be an SIHOST2 */ *(maddr + SIPLRESET) = 0; *(maddr + SIPLIRQCLR) = 0; *(maddr + SIPLIRQSET) = 0x10; type = SIHOST2; ramsize = SIHOST2_RAMSIZE; goto got_card; /* * Its not a MK II, so try for a MK I (SIHOST) */try_mk1: *(maddr+SIRESET) = 0x0; /* reset the card */ *(maddr+SIINTCL) = 0x0; /* clear int */ *(maddr+SIRAM) = 0x17; if (*(maddr+SIRAM) != (BYTE)0x17) goto fail; *(maddr+0x7ff8) = 0x17; if (*(maddr+0x7ff8) != (BYTE)0x17) { DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: 0x17 check fail at phys 0x%x = 0x%x\n", id->id_unit, paddr+0x77f8, *(maddr+0x77f8))); goto fail; } /* It must be an SIHOST (maybe?) - there must be a better way XXX */ type = SIHOST; ramsize = SIHOST_RAMSIZE;got_card: DPRINT((0, DBG_AUTOBOOT, "si%d: found type %d card, try memory test\n", id->id_unit, type)); /* Try the acid test */ ux = maddr + SIRAM; for (i = 0; i < ramsize; i++, ux++) *ux = (BYTE)(i&0xff); ux = maddr + SIRAM; for (i = 0; i < ramsize; i++, ux++) { if ((was = *ux) != (BYTE)(i&0xff)) { DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: match fail at phys 0x%x, was %x should be %x\n", id->id_unit, paddr + i, was, i&0xff)); goto fail; } } /* clear out the RAM */ ux = maddr + SIRAM; for (i = 0; i < ramsize; i++) *ux++ = 0; ux = maddr + SIRAM; for (i = 0; i < ramsize; i++) { if ((was = *ux++) != 0) { DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: clear fail at phys 0x%x, was %x\n", id->id_unit, paddr + i, was)); goto fail; } } /* * Success, we've found a valid board, now fill in * the adapter structure. */ switch (type) { case SIHOST2: if ((id->id_irq & (IRQ11|IRQ12|IRQ15)) == 0) {bad_irq: DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: bad IRQ value - %d\n", id->id_unit, id->id_irq)); return(0); } id->id_msize = SIHOST2_MEMSIZE; break; case SIHOST: if ((id->id_irq & (IRQ11|IRQ12|IRQ15)) == 0) { goto bad_irq; } id->id_msize = SIHOST_MEMSIZE; break; case SIJETISA: if ((id->id_irq & (IRQ9|IRQ10|IRQ11|IRQ12|IRQ15)) == 0) { goto bad_irq; } id->id_msize = SIJETISA_MEMSIZE; break; case SIMCA: /* MCA */ default: printf("si%d: %s not supported\n", id->id_unit, si_type[type]); return(0); } id->id_intr = (inthand2_t *)si_intr; /* set here instead of config */ si_softc[id->id_unit].sc_type = type; si_softc[id->id_unit].sc_typename = si_type[type]; return(-1); /* -1 == found */}/* * We have to make an 8 bit version of bcopy, since some cards can't * deal with 32 bit I/O */#if 1static voidsi_bcopy(const void *src, void *dst, size_t len){ while (len--) *(((u_char *)dst)++) = *(((u_char *)src)++);}#else#define si_bcopy bcopy#endif/* * Attach the device. Initialize the card. * * This routine also gets called by the EISA and PCI attach routines. * It presumes that the softstate for the unit has had had its type field * and the EISA specific stuff filled in, as well as the kernel virtual * base address and the unit number of the isa_device struct. */static intsiattach(id) struct isa_device *id;{ int unit = id->id_unit; struct si_softc *sc = &si_softc[unit]; struct si_port *pp; volatile struct si_channel *ccbp; volatile struct si_reg *regp; volatile caddr_t maddr; struct si_module *modp; struct tty *tp; struct speedtab *spt; int nmodule, nport, x, y; int uart_type; DPRINT((0, DBG_AUTOBOOT, "si%d: siattach\n", id->id_unit)); sc->sc_paddr = (caddr_t)vtophys(id->id_maddr); sc->sc_maddr = id->id_maddr; sc->sc_irq = id->id_irq; DPRINT((0, DBG_AUTOBOOT, "si%d: type: %s paddr: %x maddr: %x\n", unit, sc->sc_typename, sc->sc_paddr, sc->sc_maddr)); sc->sc_ports = NULL; /* mark as uninitialised */ maddr = sc->sc_maddr; /* Stop the CPU first so it won't stomp around while we load */ switch (sc->sc_type) {#if NEISA > 0 case SIEISA: outb(sc->sc_eisa_iobase + 2, sc->sc_eisa_irq << 4); break;#endif#if NPCI > 0 case SIPCI: *(maddr+SIPCIRESET) = 0; break; case SIJETPCI: /* fall through to JET ISA */#endif case SIJETISA: *(maddr+SIJETCONFIG) = 0; break; case SIHOST2: *(maddr+SIPLRESET) = 0; break; case SIHOST: *(maddr+SIRESET) = 0; break; default: /* this should never happen */ printf("si%d: unsupported configuration\n", unit); return 0; break; } /* OK, now lets download the download code */ if (SI_ISJET(sc->sc_type)) { DPRINT((0, DBG_DOWNLOAD, "si%d: jet_download: nbytes %d\n", id->id_unit, si3_t225_dsize)); si_bcopy(si3_t225_download, maddr + si3_t225_downloadaddr, si3_t225_dsize); DPRINT((0, DBG_DOWNLOAD, "si%d: jet_bootstrap: nbytes %d -> %x\n", id->id_unit, si3_t225_bsize, si3_t225_bootloadaddr)); si_bcopy(si3_t225_bootstrap, maddr + si3_t225_bootloadaddr, si3_t225_bsize); } else { DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n", id->id_unit, si2_z280_dsize)); si_bcopy(si2_z280_download, maddr + si2_z280_downloadaddr, si2_z280_dsize); } /* Now start the CPU */ switch (sc->sc_type) {#if NEISA > 0 case SIEISA: /* modify the download code to tell it that it's on an EISA */ *(maddr + 0x42) = 1; outb(sc->sc_eisa_iobase + 2, (sc->sc_eisa_irq << 4) | 4); (void)inb(sc->sc_eisa_iobase + 3); /* reset interrupt */ break;#endif case SIPCI: /* modify the download code to tell it that it's on a PCI */ *(maddr+0x42) = 1; *(maddr+SIPCIRESET) = 1; *(maddr+SIPCIINTCL) = 0; break; case SIJETPCI: *(maddr+SIJETRESET) = 0; *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN; break; case SIJETISA: *(maddr+SIJETRESET) = 0; switch (sc->sc_irq) { case IRQ9: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0x90; break; case IRQ10: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xa0; break; case IRQ11: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xb0; break; case IRQ12: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xc0; break; case IRQ15: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xf0; break; } break; case SIHOST: *(maddr+SIRESET_CL) = 0; *(maddr+SIINTCL_CL) = 0; break; case SIHOST2: *(maddr+SIPLRESET) = 0x10; switch (sc->sc_irq) { case IRQ11: *(maddr+SIPLIRQ11) = 0x10; break; case IRQ12: *(maddr+SIPLIRQ12) = 0x10; break; case IRQ15: *(maddr+SIPLIRQ15) = 0x10; break; } *(maddr+SIPLIRQCLR) = 0x10; break; default: /* this should _REALLY_ never happen */ printf("si%d: Uh, it was supported a second ago...\n", unit); return 0; } DELAY(1000000); /* wait around for a second */ regp = (struct si_reg *)maddr; y = 0; /* wait max of 5 sec for init OK */ while (regp->initstat == 0 && y++ < 10) { DELAY(500000); } switch (regp->initstat) { case 0: printf("si%d: startup timeout - aborting\n", unit); sc->sc_type = SIEMPTY; return 0; case 1: if (SI_ISJET(sc->sc_type)) { /* set throttle to 100 times per second */ regp->int_count = JET_INT_COUNT; /* rx_intr_count is a NOP in Jet */ } else { /* set throttle to 125 times per second */ regp->int_count = INT_COUNT; /* rx intr max of 25 times per second */ regp->rx_int_count = RXINT_COUNT; } regp->int_pending = 0; /* no intr pending */ regp->int_scounter = 0; /* reset counter */ break; case 0xff: /* * No modules found, so give up on this one. */ printf("si%d: %s - no ports found\n", unit, si_type[sc->sc_type]); return 0; default: printf("si%d: download code version error - initstat %x\n", unit, regp->initstat); return 0; } /* * First time around the ports just count them in order * to allocate some memory. */ nport = 0; modp = (struct si_module *)(maddr + 0x80); for (;;) { DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp)); switch (modp->sm_type) { case TA4: DPRINT((0, DBG_DOWNLOAD, "si%d: Found old TA4 module, 4 ports\n", unit)); x = 4; break; case TA8: DPRINT((0, DBG_DOWNLOAD, "si%d: Found old TA8 module, 8 ports\n", unit)); x = 8; break; case TA4_ASIC: DPRINT((0, DBG_DOWNLOAD, "si%d: Found ASIC TA4 module, 4 ports\n", unit)); x = 4; break; case TA8_ASIC: DPRINT((0, DBG_DOWNLOAD, "si%d: Found ASIC TA8 module, 8 ports\n", unit)); x = 8; break; case MTA: DPRINT((0, DBG_DOWNLOAD, "si%d: Found CD1400 module, 8 ports\n", unit)); x = 8; break; case SXDC: DPRINT((0, DBG_DOWNLOAD, "si%d: Found SXDC module, 8 ports\n", unit)); x = 8; break; default: printf("si%d: unknown module type %d\n", unit, modp->sm_type); goto try_next; } /* this was limited in firmware and is also a driver issue */ if ((nport + x) > SI_MAXPORTPERCARD) { printf("si%d: extra ports ignored\n", unit); goto try_next; } nport += x; si_Nports += x; si_Nmodules++;try_next: if (modp->sm_next == 0) break; modp = (struct si_module *) (maddr + (unsigned)(modp->sm_next & 0x7fff)); } sc->sc_ports = (struct si_port *)malloc(sizeof(struct si_port) * nport, M_DEVBUF, M_NOWAIT); if (sc->sc_ports == 0) {mem_fail: printf("si%d: fail to malloc memory for port structs\n", unit); return 0; } bzero(sc->sc_ports, sizeof(struct si_port) * nport); sc->sc_nport = nport; /* * allocate tty structures for ports */ tp = (struct tty *)malloc(sizeof(*tp) * nport, M_DEVBUF, M_NOWAIT); if (tp == 0) goto mem_fail; bzero(tp, sizeof(*tp) * nport); si_tty = tp; /* * Scan round the ports again, this time initialising. */ pp = sc->sc_ports; nmodule = 0; modp = (struct si_module *)(maddr + 0x80); uart_type = 1000; /* arbitary, > uchar_max */ for (;;) { switch (modp->sm_type) { case TA4: nport = 4; break; case TA8: nport = 8; break; case TA4_ASIC: nport = 4; break; case TA8_ASIC: nport = 8; break; case MTA: nport = 8; break; case SXDC: nport = 8; break; default: goto try_next2; } nmodule++; ccbp = (struct si_channel *)((char *)modp + 0x100); if (uart_type == 1000) uart_type = ccbp->type; else if (uart_type != ccbp->type) printf("si%d: Warning: module %d mismatch! (%d%s != %d%s)\n", unit, nmodule, ccbp->type, si_modulename(sc->sc_type, ccbp->type), uart_type, si_modulename(sc->sc_type, uart_type)); for (x = 0; x < nport; x++, pp++, ccbp++) { pp->sp_ccb = ccbp; /* save the address */ pp->sp_tty = tp++; pp->sp_pend = IDLE_CLOSE; pp->sp_state = 0; /* internal flag */ pp->sp_dtr_wait = 3 * hz; pp->sp_iin.c_iflag = TTYDEF_IFLAG; pp->sp_iin.c_oflag = TTYDEF_OFLAG; pp->sp_iin.c_cflag = TTYDEF_CFLAG; pp->sp_iin.c_lflag = TTYDEF_LFLAG; termioschars(&pp->sp_iin); pp->sp_iin.c_ispeed = pp->sp_iin.c_ospeed = TTYDEF_SPEED;; pp->sp_iout = pp->sp_iin; }try_next2: if (modp->sm_next == 0) { printf("si%d: card: %s, ports: %d, modules: %d, type: %d%s\n", unit, sc->sc_typename, sc->sc_nport, nmodule, uart_type, si_modulename(sc->sc_type, uart_type)); break; } modp = (struct si_module *) (maddr + (unsigned)(modp->sm_next & 0x7fff)); } if (done_chartimes == 0) { for (spt = chartimes ; spt->sp_speed != -1; spt++) { if ((spt->sp_code /= hz) == 0) spt->sp_code = 1; } done_chartimes = 1; }#ifdef DEVFS/* path name devsw minor type uid gid perm*/ for ( x = 0; x < sc->sc_nport; x++ ) { /* sync with the manuals that start at 1 */ y = x + 1 + id->id_unit * (1 << SI_CARDSHIFT); sc->devfs_token[x].ttya = devfs_add_devswf( &si_cdevsw, x, DV_CHR, 0, 0, 0600, "ttyA%02d", y); sc->devfs_token[x].cuaa = devfs_add_devswf( &si_cdevsw, x + 0x00080, DV_CHR, 0, 0, 0600, "cuaA%02d", y); sc->devfs_token[x].ttyi = devfs_add_devswf( &si_cdevsw, x + 0x10000, DV_CHR, 0, 0, 0600, "ttyiA%02d", y); sc->devfs_token[x].cuai = devfs_add_devswf( &si_cdevsw, x + 0x10080, DV_CHR, 0, 0, 0600, "cuaiA%02d", y); sc->devfs_token[x].ttyl = devfs_add_devswf( &si_cdevsw, x + 0x20000,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -