diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c index d5c04cfdf01a..ce78917bdf65 100644 --- a/sys/pc98/cbus/sio.c +++ b/sys/pc98/cbus/sio.c @@ -199,12 +199,6 @@ #define enable_intr() COM_ENABLE_INTR() #endif /* SMP */ -#ifndef EXTRA_SIO -#define EXTRA_SIO 4 /* XXX shouldn't need NSIO */ -#endif - -#define NSIOTOT (NSIO + EXTRA_SIO) - #define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ #define CALLOUT_MASK 0x80 @@ -515,6 +509,7 @@ static int sio_timeout; static int sio_timeouts_until_log; static struct callout_handle sio_timeout_handle = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle); +static int sio_numunits; #ifdef PC98 struct siodev { @@ -532,7 +527,8 @@ static int sysclock; #define PC98_CHECK_MODEM_INTERVAL (hz/10) #define DCD_OFF_TOLERANCE 2 #define DCD_ON_RECOGNITION 2 -#define IS_8251(if_type) (!(if_type & 0x10)) +#define GET_IFTYPE(flags) ((flags >> 24) & 0x1f) +#define IS_8251(if_type) (!(if_type & 0x10)) #define COM1_EXT_CLOCK 0x40000 static void commint __P((dev_t dev)); @@ -875,11 +871,23 @@ sysctl_machdep_comdefaultrate SYSCTL_HANDLER_ARGS SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW, 0, 0, sysctl_machdep_comdefaultrate, "I", ""); +#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit)) +#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit)) + #if NCARD > 0 static int sio_pccard_probe(dev) device_t dev; { + const char *name; + + name = pccard_get_name(dev); + if (strcmp(name, "sio")) + return ENXIO; + + /* Do not probe IRQ - pccardd has not arranged for it yet */ + SET_FLAG(dev, COM_C_NOPROBE); + return (sioprobe(dev)); } @@ -930,8 +938,6 @@ sio_pccard_detach(dev) } #endif /* NCARD > 0 */ -#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit)) -#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit)) static struct isa_pnp_id sio_ids[] = { {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ @@ -972,7 +978,10 @@ static int sioprobe(dev) device_t dev; { +#if 0 static bool_t already_init; + device_t xdev; +#endif bool_t failures[10]; int fn; device_t idev; @@ -981,7 +990,10 @@ sioprobe(dev) intrmask_t irqs; u_char mcr_image; int result; - device_t xdev; +#ifdef COM_MULTIPORT + Port_t xiobase; +#endif + int xirq; u_int flags = device_get_flags(dev); int rid; struct resource *port; @@ -990,7 +1002,7 @@ sioprobe(dev) int tmp; int port_shift = 0; struct siodev iod; - Port_t rsabase = NULL; + Port_t rsabase; #endif rid = 0; @@ -1004,6 +1016,14 @@ sioprobe(dev) if (!port) return ENXIO; +#if 0 + /* + * XXX this is broken - when we are first called, there are no + * previously configured IO ports. We could hard code + * 0x3f8, 0x2f8, 0x3e8, 0x2e8 etc but that's probably worse. + * This code has been doing nothing since the conversion since + * "count" is zero the first time around. + */ if (!already_init) { /* * Turn off MCR_IENABLE for all likely serial ports. An unused @@ -1012,34 +1032,39 @@ sioprobe(dev) * XXX the gate enable is elsewhere for some multiports. */ device_t *devs; - int count, i; + int count, i, xioport; +#ifdef PC98 + int xiftype; +#endif devclass_get_devices(sio_devclass, &devs, &count); #ifdef PC98 for (i = 0; i < count; i++) { xdev = devs[i]; - if (device_is_enabled(xdev)) { - tmp = (flags >> 24) & 0xff; - if (IS_8251(tmp)) - outb((isa_get_port(xdev) & 0xff00) | PC98SIO_cmd_port(tmp & 0x0f), 0xf2); - else - if (tmp == COM_IF_RSA98III) { - rsabase = isa_get_port(xdev) & 0xfff0; - outb(isa_get_port(xdev) + 8 + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0); - } else - outb(isa_get_port(xdev) + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0); + xioport = bus_get_resource_start(xdev, SYS_RES_IOPORT, 0); + xiftype = GET_IFTYPE(device_get_flags(xdev)); + if (device_is_enabled(xdev) && xioport > 0) { + if (IS_8251(xiftype)) + outb(xioport & 0xff00) | PC98SIO_cmd_port(xiftype & 0x0f), 0xf2); + else { + if (xiftype == COM_IF_RSA98III) + xioport += 8; + outb(xioport + (com_mcr << if_16550a_type[xiftype & 0x0f].port_shift), 0); + } } } #else for (i = 0; i < count; i++) { xdev = devs[i]; - if (device_is_enabled(xdev)) - outb(isa_get_port(xdev) + com_mcr, 0); + xioport = bus_get_resource_start(xdev, SYS_RES_IOPORT, 0); + if (device_is_enabled(xdev) && xioport > 0) + outb(xioport + com_mcr, 0); } #endif free(devs, M_TEMP); already_init = TRUE; } +#endif if (COM_LLCONSOLE(flags)) { printf("sio%d: reserved for low-level i/o\n", @@ -1105,12 +1130,39 @@ sioprobe(dev) */ idev = dev; mcr_image = MCR_IENABLE; +#ifdef COM_MULTIPORT + if (COM_ISMULTIPORT(flags) && !COM_NOTAST4(flags)) { + idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags)); + if (idev == NULL) { + printf("sio%d: master device %d not configured\n", + device_get_unit(dev), COM_MPMASTER(flags)); + idev = dev; + } +#ifndef PC98 + xiobase = bus_get_resource_start(idev, SYS_RES_IOPORT, 0); + if (xiobase > 0) { + xirq = bus_get_resource_start(idev, SYS_RES_IRQ, 0); + outb(xiobase + com_scr, xirq >= 0 ? 0x80 : 0); + } +#endif + mcr_image = 0; + } +#endif /* COM_MULTIPORT */ + if (bus_get_resource_start(idev, SYS_RES_IRQ, 0) <= 0) + mcr_image = 0; + + bzero(failures, sizeof failures); + iobase = rman_get_start(port); + #ifdef PC98 if (iod.if_type == COM_IF_RSA98III) { mcr_image = 0; - rsabase = isa_get_port(idev) & 0xfff0; - if (rsabase != isa_get_port(idev)) + + rsabase = iobase & 0xfff0; + if (rsabase != iobase) return(0); + iobase += 8; + outb(rsabase + rsa_msr, 0x04); outb(rsabase + rsa_frr, 0x00); if ((inb(rsabase + rsa_srr) & 0x36) != 0x36) @@ -1120,28 +1172,7 @@ sioprobe(dev) outb(rsabase + rsa_tivsr, 0x00); outb(rsabase + rsa_tcr, 0x00); } -#endif /* PC98 */ -#ifdef COM_MULTIPORT - if (COM_ISMULTIPORT(flags)) { - idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags)); - if (idev == NULL) { - printf("sio%d: master device %d not configured\n", - device_get_unit(dev), COM_MPMASTER(flags)); - idev = dev; - } -#ifndef PC98 - if (!COM_NOTAST4(flags)) { - outb(isa_get_port(idev) + com_scr, - isa_get_irq(idev) >= 0 ? 0x80 : 0); - mcr_image = 0; - } -#endif /* !PC98 */ - } -#endif /* COM_MULTIPORT */ - if (isa_get_irq(idev) < 0) - mcr_image = 0; -#ifdef PC98 tmp = if_16550a_type[iod.if_type & 0x0f].irr_write; if (tmp != -1) { /* MC16550II */ @@ -1159,12 +1190,6 @@ sioprobe(dev) } port_shift = if_16550a_type[iod.if_type & 0x0f].port_shift; #endif - bzero(failures, sizeof failures); - iobase = rman_get_start(port); -#ifdef PC98 - if (iod.if_type == COM_IF_RSA98III) - iobase += 8; -#endif /* * We don't want to get actual interrupts, just masked ones. @@ -1277,40 +1302,49 @@ sioprobe(dev) /* * Some pcmcia cards have the "TXRDY bug", so we check everyone * for IIR_TXRDY implementation ( Palido 321s, DC-1S... ) - * XXX Bruce, is this OK? XXX */ -#if 0 - /* Reading IIR register twice */ - for ( fn = 0; fn < 2; fn ++ ) { - DELAY(10000); + if (COM_NOPROBE(flags)) { + /* Reading IIR register twice */ + for (fn = 0; fn < 2; fn ++) { + DELAY(10000); #ifdef PC98 - failures[6] = inb(iobase + (com_iir << port_shift)); + failures[6] = inb(iobase + (com_iir << port_shift)); #else - failures[6] = inb(iobase + com_iir); + failures[6] = inb(iobase + com_iir); #endif - } - /* Check IIR_TXRDY clear ? */ - result = 0; - if ( failures[6] & IIR_TXRDY ) { - /* Nop, Double check with clearing IER */ -#ifdef PC98 - outb(iobase + (com_ier << port_shift), 0); - if (inb(iobase + (com_iir << port_shift)) & IIR_NOPEND) { -#else - outb(iobase + com_ier, 0); - if ( inb(iobase + com_iir) & IIR_NOPEND ) { -#endif - /* Ok. we're familia this gang */ - SET_FLAG(dev, COM_C_IIR_TXRDYBUG); /* Set IIR_TXRDYBUG */ - } else { - /* Unknown, Just omit this chip.. XXX */ - result = ENXIO; } - } else { - /* OK. this is well-known guys */ - CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); /*Clear IIR_TXRDYBUG*/ - } + /* Check IIR_TXRDY clear ? */ + result = 0; + if (failures[6] & IIR_TXRDY) { + /* Nop, Double check with clearing IER */ +#ifdef PC98 + outb(iobase + (com_ier << port_shift), 0); + if (inb(iobase + (com_iir << port_shift)) + & IIR_NOPEND) { +#else + outb(iobase + com_ier, 0); + if (inb(iobase + com_iir) & IIR_NOPEND) { #endif + /* Ok. we're familia this gang */ + SET_FLAG(dev, COM_C_IIR_TXRDYBUG); + } else { + /* Unknown, Just omit this chip.. XXX */ + result = ENXIO; + } + } else { + /* OK. this is well-known guys */ + CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); + } +#ifdef PC98 + outb(iobase + (com_cfcr << port_shift), CFCR_8BITS); +#else + outb(iobase + com_cfcr, CFCR_8BITS); +#endif + enable_intr(); + bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + return (iobase == siocniobase ? 0 : result); + } + /* * Check that * o the CFCR, IER and MCR in UART hold the values written to them @@ -1386,10 +1420,11 @@ sioprobe(dev) enable_intr(); irqs = irqmap[1] & ~irqmap[0]; - if (isa_get_irq(idev) >= 0 && ((1 << isa_get_irq(idev)) & irqs) == 0) + xirq = bus_get_resource_start(idev, SYS_RES_IRQ, 0); + if (xirq >= 0 && ((1 << xirq) & irqs) == 0) printf( "sio%d: configured irq %d not in bitmap of probed irqs %#x\n", - device_get_unit(dev), isa_get_irq(idev), irqs); + device_get_unit(dev), xirq, irqs); if (bootverbose) printf("sio%d: irq maps: %#x %#x %#x %#x\n", device_get_unit(dev), @@ -1514,11 +1549,13 @@ sioattach(dev) Port_t *espp; #endif Port_t iobase; + int irq; int unit; void *ih; - u_int flags = device_get_flags(dev); + u_int flags; int rid; struct resource *port; + int ret; #ifdef PC98 int port_shift = 0; u_char *obuf; @@ -1537,16 +1574,20 @@ sioattach(dev) return ENXIO; iobase = rman_get_start(port); -#ifdef PC98 - if (((flags >> 24) & 0xff) == COM_IF_RSA98III) - iobase += 8; -#endif + irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0); unit = device_get_unit(dev); com = device_get_softc(dev); + flags = device_get_flags(dev); + + if (unit >= sio_numunits) + sio_numunits = unit + 1; + #ifdef PC98 obufsize = 256; - if (((flags >> 24) & 0xff) == COM_IF_RSA98III) + if (GET_IFTYPE(flags) == COM_IF_RSA98III) { + iobase += 8; obufsize = 2048; + } if ((obuf = malloc(obufsize * 2, M_DEVBUF, M_NOWAIT)) == NULL) return (0); bzero(obuf, obufsize * 2); @@ -1575,15 +1616,15 @@ sioattach(dev) com->cfcr_image = CFCR_8BITS; com->dtr_wait = 3 * hz; com->loses_outints = COM_LOSESOUTINTS(flags) != 0; - com->no_irq = isa_get_irq(dev) < 0; + com->no_irq = irq < 0; com->tx_fifo_size = 1; com->obufs[0].l_head = com->obuf1; com->obufs[1].l_head = com->obuf2; com->iobase = iobase; #ifdef PC98 - if (pc98_set_ioport(com, device_get_flags(dev)) == -1) { - com->pc98_if_type = (device_get_flags(dev) >> 24) & 0xff; + if (pc98_set_ioport(com, flags) == -1) { + com->pc98_if_type = GET_IFTYPE(flags); port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift; com->data_port = iobase + (com_data << port_shift); com->int_id_port = iobase + (com_iir << port_shift); @@ -1808,14 +1849,18 @@ determined_type: ; #ifdef COM_MULTIPORT if (COM_ISMULTIPORT(flags)) { + device_t masterdev; + int irq; + com->multiport = TRUE; printf(" (multiport"); + masterdev = devclass_get_device(sio_devclass, + COM_MPMASTER(flags)); + irq = bus_get_resource_start(masterdev, SYS_RES_IRQ, 0); + com->no_irq = irq < 0; if (unit == COM_MPMASTER(flags)) printf(" master"); printf(")"); - com->no_irq = - isa_get_irq(devclass_get_device - (sio_devclass, COM_MPMASTER(flags))) < 0; } #endif /* COM_MULTIPORT */ #ifdef PC98 @@ -1823,7 +1868,7 @@ determined_type: ; #endif if (unit == comconsole) printf(", console"); - if ( COM_IIR_TXRDYBUG(flags) ) + if (COM_IIR_TXRDYBUG(flags)) printf(" with a bogus IIR_TXRDY register"); printf("\n"); @@ -1849,10 +1894,14 @@ determined_type: ; rid = 0; com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, - RF_SHAREABLE | RF_ACTIVE); - BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, - INTR_TYPE_TTY | INTR_TYPE_FAST, - siointr, com, &ih); + RF_ACTIVE); + if (com->irqres) { + ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, + INTR_TYPE_TTY | INTR_TYPE_FAST, + siointr, com, &ih); + if (ret) + device_printf(dev, "could not activate interrupt\n"); + } return (0); } @@ -1877,7 +1926,8 @@ sioopen(dev, flag, mode, p) mynor = minor(dev); unit = MINOR_TO_UNIT(mynor); - if ((u_int) unit >= NSIOTOT || (com = com_addr(unit)) == NULL) + com = com_addr(unit); + if (com == NULL) return (ENXIO); if (com->gone) return (ENXIO); @@ -2462,7 +2512,7 @@ siointr(arg) COM_LOCK(); do { possibly_more_intrs = FALSE; - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { com = com_addr(unit); /* * XXX COM_LOCK(); @@ -2765,7 +2815,7 @@ cont: com->obufq.l_next = qp; } else { /* output just completed */ - if ( COM_IIR_TXRDYBUG(com->flags) ) { + if (COM_IIR_TXRDYBUG(com->flags)) { int_ctl_new = int_ctl & ~IER_ETXRDY; } com->state &= ~CS_BUSY; @@ -2781,12 +2831,12 @@ cont: setsofttty(); /* handle at high level ASAP */ } } - if ( COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) { + if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) { #ifdef PC98 if (com->pc98_if_type == COM_IF_RSA98III) { - int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY); - outb(com->intr_ctl_port, int_ctl_new); - outb(com->rsabase + rsa_ier, 0x1d); + int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY); + outb(com->intr_ctl_port, int_ctl_new); + outb(com->rsabase + rsa_ier, 0x1d); } else #endif outb(com->intr_ctl_port, int_ctl_new); @@ -3054,7 +3104,7 @@ siopoll() if (com_events == 0) return; repeat: - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { struct com_s *com; int incc; struct tty *tp; @@ -3744,7 +3794,7 @@ siosettimeout() untimeout(comwakeup, (void *)NULL, sio_timeout_handle); sio_timeout = hz; someopen = FALSE; - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { com = com_addr(unit); if (com != NULL && com->tp != NULL && com->tp->t_state & TS_ISOPEN && !com->gone) { @@ -3780,7 +3830,7 @@ comwakeup(chan) * Recover from lost output interrupts. * Poll any lines that don't use interrupts. */ - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { com = com_addr(unit); if (com != NULL && !com->gone && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { @@ -3796,7 +3846,7 @@ comwakeup(chan) if (--sio_timeouts_until_log > 0) return; sio_timeouts_until_log = hz / sio_timeout; - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { int errnum; com = com_addr(unit); @@ -3958,7 +4008,7 @@ siocngetspeed(iobase, table) code = dlbh << 8 | dlbl; - for ( ; table->sp_speed != -1; table++) + for (; table->sp_speed != -1; table++) if (table->sp_code == code) return (table->sp_speed); @@ -4810,7 +4860,7 @@ pc98_check_if_type(device_t dev, struct siodev *iod) { 3, 10, 12, 13, 5, 6, 9, -1} }; - iod->if_type = if_type = (device_get_flags(dev) >> 24) & 0xff; + iod->if_type = if_type = GET_IFTYPE(device_get_flags(dev)); if ((if_type < 0 || if_type > COM_IF_END1) && (if_type < 0x10 || if_type > COM_IF_END2)) return(-1); @@ -4876,7 +4926,7 @@ pc98_set_ioport( struct com_s *com, int id_flags ) { int io, if_type; - if_type = (id_flags >> 24) & 0xff; + if_type = GET_IFTYPE(id_flags); if (IS_8251(if_type)) { pc98_check_sysclock(); io = com->iobase & 0xff00; diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c index d5c04cfdf01a..ce78917bdf65 100644 --- a/sys/pc98/pc98/sio.c +++ b/sys/pc98/pc98/sio.c @@ -199,12 +199,6 @@ #define enable_intr() COM_ENABLE_INTR() #endif /* SMP */ -#ifndef EXTRA_SIO -#define EXTRA_SIO 4 /* XXX shouldn't need NSIO */ -#endif - -#define NSIOTOT (NSIO + EXTRA_SIO) - #define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ #define CALLOUT_MASK 0x80 @@ -515,6 +509,7 @@ static int sio_timeout; static int sio_timeouts_until_log; static struct callout_handle sio_timeout_handle = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle); +static int sio_numunits; #ifdef PC98 struct siodev { @@ -532,7 +527,8 @@ static int sysclock; #define PC98_CHECK_MODEM_INTERVAL (hz/10) #define DCD_OFF_TOLERANCE 2 #define DCD_ON_RECOGNITION 2 -#define IS_8251(if_type) (!(if_type & 0x10)) +#define GET_IFTYPE(flags) ((flags >> 24) & 0x1f) +#define IS_8251(if_type) (!(if_type & 0x10)) #define COM1_EXT_CLOCK 0x40000 static void commint __P((dev_t dev)); @@ -875,11 +871,23 @@ sysctl_machdep_comdefaultrate SYSCTL_HANDLER_ARGS SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW, 0, 0, sysctl_machdep_comdefaultrate, "I", ""); +#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit)) +#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit)) + #if NCARD > 0 static int sio_pccard_probe(dev) device_t dev; { + const char *name; + + name = pccard_get_name(dev); + if (strcmp(name, "sio")) + return ENXIO; + + /* Do not probe IRQ - pccardd has not arranged for it yet */ + SET_FLAG(dev, COM_C_NOPROBE); + return (sioprobe(dev)); } @@ -930,8 +938,6 @@ sio_pccard_detach(dev) } #endif /* NCARD > 0 */ -#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit)) -#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit)) static struct isa_pnp_id sio_ids[] = { {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ @@ -972,7 +978,10 @@ static int sioprobe(dev) device_t dev; { +#if 0 static bool_t already_init; + device_t xdev; +#endif bool_t failures[10]; int fn; device_t idev; @@ -981,7 +990,10 @@ sioprobe(dev) intrmask_t irqs; u_char mcr_image; int result; - device_t xdev; +#ifdef COM_MULTIPORT + Port_t xiobase; +#endif + int xirq; u_int flags = device_get_flags(dev); int rid; struct resource *port; @@ -990,7 +1002,7 @@ sioprobe(dev) int tmp; int port_shift = 0; struct siodev iod; - Port_t rsabase = NULL; + Port_t rsabase; #endif rid = 0; @@ -1004,6 +1016,14 @@ sioprobe(dev) if (!port) return ENXIO; +#if 0 + /* + * XXX this is broken - when we are first called, there are no + * previously configured IO ports. We could hard code + * 0x3f8, 0x2f8, 0x3e8, 0x2e8 etc but that's probably worse. + * This code has been doing nothing since the conversion since + * "count" is zero the first time around. + */ if (!already_init) { /* * Turn off MCR_IENABLE for all likely serial ports. An unused @@ -1012,34 +1032,39 @@ sioprobe(dev) * XXX the gate enable is elsewhere for some multiports. */ device_t *devs; - int count, i; + int count, i, xioport; +#ifdef PC98 + int xiftype; +#endif devclass_get_devices(sio_devclass, &devs, &count); #ifdef PC98 for (i = 0; i < count; i++) { xdev = devs[i]; - if (device_is_enabled(xdev)) { - tmp = (flags >> 24) & 0xff; - if (IS_8251(tmp)) - outb((isa_get_port(xdev) & 0xff00) | PC98SIO_cmd_port(tmp & 0x0f), 0xf2); - else - if (tmp == COM_IF_RSA98III) { - rsabase = isa_get_port(xdev) & 0xfff0; - outb(isa_get_port(xdev) + 8 + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0); - } else - outb(isa_get_port(xdev) + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0); + xioport = bus_get_resource_start(xdev, SYS_RES_IOPORT, 0); + xiftype = GET_IFTYPE(device_get_flags(xdev)); + if (device_is_enabled(xdev) && xioport > 0) { + if (IS_8251(xiftype)) + outb(xioport & 0xff00) | PC98SIO_cmd_port(xiftype & 0x0f), 0xf2); + else { + if (xiftype == COM_IF_RSA98III) + xioport += 8; + outb(xioport + (com_mcr << if_16550a_type[xiftype & 0x0f].port_shift), 0); + } } } #else for (i = 0; i < count; i++) { xdev = devs[i]; - if (device_is_enabled(xdev)) - outb(isa_get_port(xdev) + com_mcr, 0); + xioport = bus_get_resource_start(xdev, SYS_RES_IOPORT, 0); + if (device_is_enabled(xdev) && xioport > 0) + outb(xioport + com_mcr, 0); } #endif free(devs, M_TEMP); already_init = TRUE; } +#endif if (COM_LLCONSOLE(flags)) { printf("sio%d: reserved for low-level i/o\n", @@ -1105,12 +1130,39 @@ sioprobe(dev) */ idev = dev; mcr_image = MCR_IENABLE; +#ifdef COM_MULTIPORT + if (COM_ISMULTIPORT(flags) && !COM_NOTAST4(flags)) { + idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags)); + if (idev == NULL) { + printf("sio%d: master device %d not configured\n", + device_get_unit(dev), COM_MPMASTER(flags)); + idev = dev; + } +#ifndef PC98 + xiobase = bus_get_resource_start(idev, SYS_RES_IOPORT, 0); + if (xiobase > 0) { + xirq = bus_get_resource_start(idev, SYS_RES_IRQ, 0); + outb(xiobase + com_scr, xirq >= 0 ? 0x80 : 0); + } +#endif + mcr_image = 0; + } +#endif /* COM_MULTIPORT */ + if (bus_get_resource_start(idev, SYS_RES_IRQ, 0) <= 0) + mcr_image = 0; + + bzero(failures, sizeof failures); + iobase = rman_get_start(port); + #ifdef PC98 if (iod.if_type == COM_IF_RSA98III) { mcr_image = 0; - rsabase = isa_get_port(idev) & 0xfff0; - if (rsabase != isa_get_port(idev)) + + rsabase = iobase & 0xfff0; + if (rsabase != iobase) return(0); + iobase += 8; + outb(rsabase + rsa_msr, 0x04); outb(rsabase + rsa_frr, 0x00); if ((inb(rsabase + rsa_srr) & 0x36) != 0x36) @@ -1120,28 +1172,7 @@ sioprobe(dev) outb(rsabase + rsa_tivsr, 0x00); outb(rsabase + rsa_tcr, 0x00); } -#endif /* PC98 */ -#ifdef COM_MULTIPORT - if (COM_ISMULTIPORT(flags)) { - idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags)); - if (idev == NULL) { - printf("sio%d: master device %d not configured\n", - device_get_unit(dev), COM_MPMASTER(flags)); - idev = dev; - } -#ifndef PC98 - if (!COM_NOTAST4(flags)) { - outb(isa_get_port(idev) + com_scr, - isa_get_irq(idev) >= 0 ? 0x80 : 0); - mcr_image = 0; - } -#endif /* !PC98 */ - } -#endif /* COM_MULTIPORT */ - if (isa_get_irq(idev) < 0) - mcr_image = 0; -#ifdef PC98 tmp = if_16550a_type[iod.if_type & 0x0f].irr_write; if (tmp != -1) { /* MC16550II */ @@ -1159,12 +1190,6 @@ sioprobe(dev) } port_shift = if_16550a_type[iod.if_type & 0x0f].port_shift; #endif - bzero(failures, sizeof failures); - iobase = rman_get_start(port); -#ifdef PC98 - if (iod.if_type == COM_IF_RSA98III) - iobase += 8; -#endif /* * We don't want to get actual interrupts, just masked ones. @@ -1277,40 +1302,49 @@ sioprobe(dev) /* * Some pcmcia cards have the "TXRDY bug", so we check everyone * for IIR_TXRDY implementation ( Palido 321s, DC-1S... ) - * XXX Bruce, is this OK? XXX */ -#if 0 - /* Reading IIR register twice */ - for ( fn = 0; fn < 2; fn ++ ) { - DELAY(10000); + if (COM_NOPROBE(flags)) { + /* Reading IIR register twice */ + for (fn = 0; fn < 2; fn ++) { + DELAY(10000); #ifdef PC98 - failures[6] = inb(iobase + (com_iir << port_shift)); + failures[6] = inb(iobase + (com_iir << port_shift)); #else - failures[6] = inb(iobase + com_iir); + failures[6] = inb(iobase + com_iir); #endif - } - /* Check IIR_TXRDY clear ? */ - result = 0; - if ( failures[6] & IIR_TXRDY ) { - /* Nop, Double check with clearing IER */ -#ifdef PC98 - outb(iobase + (com_ier << port_shift), 0); - if (inb(iobase + (com_iir << port_shift)) & IIR_NOPEND) { -#else - outb(iobase + com_ier, 0); - if ( inb(iobase + com_iir) & IIR_NOPEND ) { -#endif - /* Ok. we're familia this gang */ - SET_FLAG(dev, COM_C_IIR_TXRDYBUG); /* Set IIR_TXRDYBUG */ - } else { - /* Unknown, Just omit this chip.. XXX */ - result = ENXIO; } - } else { - /* OK. this is well-known guys */ - CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); /*Clear IIR_TXRDYBUG*/ - } + /* Check IIR_TXRDY clear ? */ + result = 0; + if (failures[6] & IIR_TXRDY) { + /* Nop, Double check with clearing IER */ +#ifdef PC98 + outb(iobase + (com_ier << port_shift), 0); + if (inb(iobase + (com_iir << port_shift)) + & IIR_NOPEND) { +#else + outb(iobase + com_ier, 0); + if (inb(iobase + com_iir) & IIR_NOPEND) { #endif + /* Ok. we're familia this gang */ + SET_FLAG(dev, COM_C_IIR_TXRDYBUG); + } else { + /* Unknown, Just omit this chip.. XXX */ + result = ENXIO; + } + } else { + /* OK. this is well-known guys */ + CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); + } +#ifdef PC98 + outb(iobase + (com_cfcr << port_shift), CFCR_8BITS); +#else + outb(iobase + com_cfcr, CFCR_8BITS); +#endif + enable_intr(); + bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + return (iobase == siocniobase ? 0 : result); + } + /* * Check that * o the CFCR, IER and MCR in UART hold the values written to them @@ -1386,10 +1420,11 @@ sioprobe(dev) enable_intr(); irqs = irqmap[1] & ~irqmap[0]; - if (isa_get_irq(idev) >= 0 && ((1 << isa_get_irq(idev)) & irqs) == 0) + xirq = bus_get_resource_start(idev, SYS_RES_IRQ, 0); + if (xirq >= 0 && ((1 << xirq) & irqs) == 0) printf( "sio%d: configured irq %d not in bitmap of probed irqs %#x\n", - device_get_unit(dev), isa_get_irq(idev), irqs); + device_get_unit(dev), xirq, irqs); if (bootverbose) printf("sio%d: irq maps: %#x %#x %#x %#x\n", device_get_unit(dev), @@ -1514,11 +1549,13 @@ sioattach(dev) Port_t *espp; #endif Port_t iobase; + int irq; int unit; void *ih; - u_int flags = device_get_flags(dev); + u_int flags; int rid; struct resource *port; + int ret; #ifdef PC98 int port_shift = 0; u_char *obuf; @@ -1537,16 +1574,20 @@ sioattach(dev) return ENXIO; iobase = rman_get_start(port); -#ifdef PC98 - if (((flags >> 24) & 0xff) == COM_IF_RSA98III) - iobase += 8; -#endif + irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0); unit = device_get_unit(dev); com = device_get_softc(dev); + flags = device_get_flags(dev); + + if (unit >= sio_numunits) + sio_numunits = unit + 1; + #ifdef PC98 obufsize = 256; - if (((flags >> 24) & 0xff) == COM_IF_RSA98III) + if (GET_IFTYPE(flags) == COM_IF_RSA98III) { + iobase += 8; obufsize = 2048; + } if ((obuf = malloc(obufsize * 2, M_DEVBUF, M_NOWAIT)) == NULL) return (0); bzero(obuf, obufsize * 2); @@ -1575,15 +1616,15 @@ sioattach(dev) com->cfcr_image = CFCR_8BITS; com->dtr_wait = 3 * hz; com->loses_outints = COM_LOSESOUTINTS(flags) != 0; - com->no_irq = isa_get_irq(dev) < 0; + com->no_irq = irq < 0; com->tx_fifo_size = 1; com->obufs[0].l_head = com->obuf1; com->obufs[1].l_head = com->obuf2; com->iobase = iobase; #ifdef PC98 - if (pc98_set_ioport(com, device_get_flags(dev)) == -1) { - com->pc98_if_type = (device_get_flags(dev) >> 24) & 0xff; + if (pc98_set_ioport(com, flags) == -1) { + com->pc98_if_type = GET_IFTYPE(flags); port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift; com->data_port = iobase + (com_data << port_shift); com->int_id_port = iobase + (com_iir << port_shift); @@ -1808,14 +1849,18 @@ determined_type: ; #ifdef COM_MULTIPORT if (COM_ISMULTIPORT(flags)) { + device_t masterdev; + int irq; + com->multiport = TRUE; printf(" (multiport"); + masterdev = devclass_get_device(sio_devclass, + COM_MPMASTER(flags)); + irq = bus_get_resource_start(masterdev, SYS_RES_IRQ, 0); + com->no_irq = irq < 0; if (unit == COM_MPMASTER(flags)) printf(" master"); printf(")"); - com->no_irq = - isa_get_irq(devclass_get_device - (sio_devclass, COM_MPMASTER(flags))) < 0; } #endif /* COM_MULTIPORT */ #ifdef PC98 @@ -1823,7 +1868,7 @@ determined_type: ; #endif if (unit == comconsole) printf(", console"); - if ( COM_IIR_TXRDYBUG(flags) ) + if (COM_IIR_TXRDYBUG(flags)) printf(" with a bogus IIR_TXRDY register"); printf("\n"); @@ -1849,10 +1894,14 @@ determined_type: ; rid = 0; com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, - RF_SHAREABLE | RF_ACTIVE); - BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, - INTR_TYPE_TTY | INTR_TYPE_FAST, - siointr, com, &ih); + RF_ACTIVE); + if (com->irqres) { + ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, + INTR_TYPE_TTY | INTR_TYPE_FAST, + siointr, com, &ih); + if (ret) + device_printf(dev, "could not activate interrupt\n"); + } return (0); } @@ -1877,7 +1926,8 @@ sioopen(dev, flag, mode, p) mynor = minor(dev); unit = MINOR_TO_UNIT(mynor); - if ((u_int) unit >= NSIOTOT || (com = com_addr(unit)) == NULL) + com = com_addr(unit); + if (com == NULL) return (ENXIO); if (com->gone) return (ENXIO); @@ -2462,7 +2512,7 @@ siointr(arg) COM_LOCK(); do { possibly_more_intrs = FALSE; - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { com = com_addr(unit); /* * XXX COM_LOCK(); @@ -2765,7 +2815,7 @@ cont: com->obufq.l_next = qp; } else { /* output just completed */ - if ( COM_IIR_TXRDYBUG(com->flags) ) { + if (COM_IIR_TXRDYBUG(com->flags)) { int_ctl_new = int_ctl & ~IER_ETXRDY; } com->state &= ~CS_BUSY; @@ -2781,12 +2831,12 @@ cont: setsofttty(); /* handle at high level ASAP */ } } - if ( COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) { + if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) { #ifdef PC98 if (com->pc98_if_type == COM_IF_RSA98III) { - int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY); - outb(com->intr_ctl_port, int_ctl_new); - outb(com->rsabase + rsa_ier, 0x1d); + int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY); + outb(com->intr_ctl_port, int_ctl_new); + outb(com->rsabase + rsa_ier, 0x1d); } else #endif outb(com->intr_ctl_port, int_ctl_new); @@ -3054,7 +3104,7 @@ siopoll() if (com_events == 0) return; repeat: - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { struct com_s *com; int incc; struct tty *tp; @@ -3744,7 +3794,7 @@ siosettimeout() untimeout(comwakeup, (void *)NULL, sio_timeout_handle); sio_timeout = hz; someopen = FALSE; - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { com = com_addr(unit); if (com != NULL && com->tp != NULL && com->tp->t_state & TS_ISOPEN && !com->gone) { @@ -3780,7 +3830,7 @@ comwakeup(chan) * Recover from lost output interrupts. * Poll any lines that don't use interrupts. */ - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { com = com_addr(unit); if (com != NULL && !com->gone && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { @@ -3796,7 +3846,7 @@ comwakeup(chan) if (--sio_timeouts_until_log > 0) return; sio_timeouts_until_log = hz / sio_timeout; - for (unit = 0; unit < NSIOTOT; ++unit) { + for (unit = 0; unit < sio_numunits; ++unit) { int errnum; com = com_addr(unit); @@ -3958,7 +4008,7 @@ siocngetspeed(iobase, table) code = dlbh << 8 | dlbl; - for ( ; table->sp_speed != -1; table++) + for (; table->sp_speed != -1; table++) if (table->sp_code == code) return (table->sp_speed); @@ -4810,7 +4860,7 @@ pc98_check_if_type(device_t dev, struct siodev *iod) { 3, 10, 12, 13, 5, 6, 9, -1} }; - iod->if_type = if_type = (device_get_flags(dev) >> 24) & 0xff; + iod->if_type = if_type = GET_IFTYPE(device_get_flags(dev)); if ((if_type < 0 || if_type > COM_IF_END1) && (if_type < 0x10 || if_type > COM_IF_END2)) return(-1); @@ -4876,7 +4926,7 @@ pc98_set_ioport( struct com_s *com, int id_flags ) { int io, if_type; - if_type = (id_flags >> 24) & 0xff; + if_type = GET_IFTYPE(id_flags); if (IS_8251(if_type)) { pc98_check_sysclock(); io = com->iobase & 0xff00;