From de48920662d0f437417af27a6fe80dc889117db8 Mon Sep 17 00:00:00 2001 From: Yoshihiro Takahashi Date: Mon, 26 Nov 2001 12:29:53 +0000 Subject: [PATCH] Split the sio driver for pc98 into bus front end and back end. (merged from the files in sys/dev/sio) --- sys/conf/files.pc98 | 6 +- sys/dev/sio/sio_pccard.c | 4 + sys/dev/sio/siovar.h | 30 ++++ sys/pc98/cbus/cbus.h | 1 - sys/pc98/cbus/sio.c | 342 ++++++++------------------------------- sys/pc98/cbus/sio_cbus.c | 95 +++++++++++ sys/pc98/pc98/pc98.h | 1 - sys/pc98/pc98/sio.c | 342 ++++++++------------------------------- sys/pc98/pc98/sio_cbus.c | 95 +++++++++++ 9 files changed, 362 insertions(+), 554 deletions(-) create mode 100644 sys/pc98/cbus/sio_cbus.c create mode 100644 sys/pc98/pc98/sio_cbus.c diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index fb1cdf86647..d1a726d5b10 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -107,6 +107,9 @@ dev/kbd/kbd.c optional sc dev/kbd/kbd.c optional ukbd dev/kbd/kbd.c count pckbd dev/lnc/if_lnc_cbus.c optional lnc isa +dev/sio/sio_pccard.c optional sio card +dev/sio/sio_pccard.c optional sio pccard +dev/sio/sio_pci.c optional sio pci dev/snc/dp83932.c optional snc dev/snc/dp83932subr.c optional snc dev/snc/if_snc.c optional snc @@ -399,8 +402,7 @@ pc98/pc98/scgdcrndr.c optional sc gdc pc98/pc98/scterm-sck.c optional sc pc98/pc98/scvtbpc98.c optional sc pc98/pc98/sio.c optional sio -#pc98/pc98/sio_pccard.c optional card -#pc98/pc98/sio_pccard.c optional pccard +pc98/pc98/sio_cbus.c optional sio isa pc98/pc98/spkr.c optional speaker pc98/pc98/syscons.c optional sc pc98/pc98/syscons_pc98.c optional sc diff --git a/sys/dev/sio/sio_pccard.c b/sys/dev/sio/sio_pccard.c index 0a409275c7d..4db2e9dd88b 100644 --- a/sys/dev/sio/sio_pccard.c +++ b/sys/dev/sio/sio_pccard.c @@ -92,6 +92,10 @@ static int sio_pccard_probe(dev) device_t dev; { + +#ifdef PC98 + SET_FLAG(dev, SET_IFTYPE(COM_IF_MODEM_CARD)); +#endif /* Do not probe IRQ - pccard doesn't turn on the interrupt line */ /* until bus_setup_intr */ return (sioprobe(dev, 0, 1)); diff --git a/sys/dev/sio/siovar.h b/sys/dev/sio/siovar.h index ebc296887d5..2c9913f218b 100644 --- a/sys/dev/sio/siovar.h +++ b/sys/dev/sio/siovar.h @@ -33,6 +33,36 @@ * $FreeBSD$ */ +#ifdef PC98 +#define COM_IF_INTERNAL 0x00 +#define COM_IF_PC9861K_1 0x01 +#define COM_IF_PC9861K_2 0x02 +#define COM_IF_IND_SS_1 0x03 +#define COM_IF_IND_SS_2 0x04 +#define COM_IF_PIO9032B_1 0x05 +#define COM_IF_PIO9032B_2 0x06 +#define COM_IF_B98_01_1 0x07 +#define COM_IF_B98_01_2 0x08 +#define COM_IF_END1 COM_IF_B98_01_2 +#define COM_IF_RSA98 0x10 /* same as COM_IF_NS16550 */ +#define COM_IF_NS16550 0x11 +#define COM_IF_SECOND_CCU 0x12 /* same as COM_IF_NS16550 */ +#define COM_IF_MC16550II 0x13 +#define COM_IF_MCRS98 0x14 /* same as COM_IF_MC16550II */ +#define COM_IF_RSB3000 0x15 +#define COM_IF_RSB384 0x16 +#define COM_IF_MODEM_CARD 0x17 +#define COM_IF_RSA98III 0x18 +#define COM_IF_ESP98 0x19 +#define COM_IF_END2 COM_IF_ESP98 + +#define GET_IFTYPE(type) (((type) >> 24) & 0x1f) +#define SET_IFTYPE(type) ((type) << 24) + +#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)) +#endif /* PC98 */ + int sioattach __P((device_t dev, int xrid)); int siodetach __P((device_t dev)); int sioprobe __P((device_t dev, int xrid, int noprobe)); diff --git a/sys/pc98/cbus/cbus.h b/sys/pc98/cbus/cbus.h index 1dc36d60094..15226d3f3b8 100644 --- a/sys/pc98/cbus/cbus.h +++ b/sys/pc98/cbus/cbus.h @@ -110,7 +110,6 @@ #define IO_ASCSIZE 5 /* AmiScan GI1904-based hand scanner */ #define IO_CGASIZE 16 /* CGA controllers */ -#define IO_COMSIZE 8 /* 8250, 16X50 com controllers (4?) */ #define IO_DMASIZE 16 /* 8237 DMA controllers */ #define IO_DPGSIZE 32 /* 74LS612 DMA page registers */ #define IO_EISASIZE 4096 /* EISA controllers */ diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c index cc231ddd09b..cf1b03a52ce 100644 --- a/sys/pc98/cbus/sio.c +++ b/sys/pc98/cbus/sio.c @@ -39,8 +39,6 @@ #include "opt_compat.h" #include "opt_ddb.h" #include "opt_sio.h" -#include "card.h" -#include "pci.h" /* * Serial driver, based on 386BSD-0.1 com driver. @@ -114,30 +112,6 @@ * modified for 8251(FIFO) by Seigo TANIMURA */ -#ifdef PC98 -#define COM_IF_INTERNAL 0x00 -#define COM_IF_PC9861K_1 0x01 -#define COM_IF_PC9861K_2 0x02 -#define COM_IF_IND_SS_1 0x03 -#define COM_IF_IND_SS_2 0x04 -#define COM_IF_PIO9032B_1 0x05 -#define COM_IF_PIO9032B_2 0x06 -#define COM_IF_B98_01_1 0x07 -#define COM_IF_B98_01_2 0x08 -#define COM_IF_END1 COM_IF_B98_01_2 -#define COM_IF_RSA98 0x10 /* same as COM_IF_NS16550 */ -#define COM_IF_NS16550 0x11 -#define COM_IF_SECOND_CCU 0x12 /* same as COM_IF_NS16550 */ -#define COM_IF_MC16550II 0x13 -#define COM_IF_MCRS98 0x14 /* same as COM_IF_MC16550II */ -#define COM_IF_RSB3000 0x15 -#define COM_IF_RSB384 0x16 -#define COM_IF_MODEM_CARD 0x17 -#define COM_IF_RSA98III 0x18 -#define COM_IF_ESP98 0x19 -#define COM_IF_END2 COM_IF_ESP98 -#endif /* PC98 */ - #include #include #include @@ -160,21 +134,17 @@ #include #include -#ifdef PC98 -#include -#include -#else -#include -#endif #include -#if NPCI > 0 -#include -#include -#endif #include #include +#include + +#ifdef PC98 +#include +#include +#endif #ifdef COM_ESP #include @@ -399,8 +369,6 @@ struct com_s { #ifdef COM_ESP static int espattach __P((struct com_s *com, Port_t esp_port)); #endif -static int sioattach __P((device_t dev, int rid)); -static int sio_isa_attach __P((device_t dev)); static timeout_t siobusycheck; static timeout_t siodtrwakeup; @@ -411,8 +379,6 @@ static void siointr __P((void *arg)); static int commctl __P((struct com_s *com, int bits, int how)); static int comparam __P((struct tty *tp, struct termios *t)); static void siopoll __P((void *)); -static int sioprobe __P((device_t dev, int xrid)); -static int sio_isa_probe __P((device_t dev)); static void siosettimeout __P((void)); static int siosetwater __P((struct com_s *com, speed_t speed)); static void comstart __P((struct tty *tp)); @@ -421,73 +387,14 @@ static timeout_t comwakeup; static void disc_optim __P((struct tty *tp, struct termios *t, struct com_s *com)); -#if NCARD > 0 -static int sio_pccard_attach __P((device_t dev)); -static int sio_pccard_detach __P((device_t dev)); -static int sio_pccard_probe __P((device_t dev)); -#endif /* NCARD > 0 */ - -#if NPCI > 0 -static int sio_pci_attach __P((device_t dev)); -static void sio_pci_kludge_unit __P((device_t dev)); -static int sio_pci_probe __P((device_t dev)); -#endif /* NPCI > 0 */ - -static char driver_name[] = "sio"; +char sio_driver_name[] = "sio"; static struct mtx sio_lock; static int sio_inited; /* table and macro for fast conversion from a unit number to its com struct */ -static devclass_t sio_devclass; +devclass_t sio_devclass; #define com_addr(unit) ((struct com_s *) \ - devclass_get_softc(sio_devclass, unit)) - -static device_method_t sio_isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_isa_probe), - DEVMETHOD(device_attach, sio_isa_attach), - - { 0, 0 } -}; - -static driver_t sio_isa_driver = { - driver_name, - sio_isa_methods, - sizeof(struct com_s), -}; - -#if NCARD > 0 -static device_method_t sio_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_pccard_probe), - DEVMETHOD(device_attach, sio_pccard_attach), - DEVMETHOD(device_detach, sio_pccard_detach), - - { 0, 0 } -}; - -static driver_t sio_pccard_driver = { - driver_name, - sio_pccard_methods, - sizeof(struct com_s), -}; -#endif /* NCARD > 0 */ - -#if NPCI > 0 -static device_method_t sio_pci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_pci_probe), - DEVMETHOD(device_attach, sio_pci_attach), - - { 0, 0 } -}; - -static driver_t sio_pci_driver = { - driver_name, - sio_pci_methods, - sizeof(struct com_s), -}; -#endif /* NPCI > 0 */ + devclass_get_softc(sio_devclass, unit)) /* XXX */ static d_open_t sioopen; static d_close_t sioclose; @@ -505,7 +412,7 @@ static struct cdevsw sio_cdevsw = { /* poll */ ttypoll, /* mmap */ nommap, /* strategy */ nostrategy, - /* name */ driver_name, + /* name */ sio_driver_name, /* maj */ CDEV_MAJOR, /* dump */ nodump, /* psize */ nopsize, @@ -549,8 +456,6 @@ static int sysclock; #define PC98_CHECK_MODEM_INTERVAL (hz/10) #define DCD_OFF_TOLERANCE 2 #define DCD_ON_RECOGNITION 2 -#define GET_IFTYPE(flags) ((flags >> 24) & 0x1f) -#define SET_IFTYPE(type) (type << 24) #define IS_8251(if_type) (!(if_type & 0x10)) #define COM1_EXT_CLOCK 0x40000 @@ -842,6 +747,7 @@ struct { #ifdef PC98 /* XXX configure this properly. */ +/* XXX quite broken for new-bus. */ static Port_t likely_com_ports[] = { 0, 0xb0, 0xb1, 0 }; static Port_t likely_esp_ports[] = { 0xc0d0, 0 }; @@ -919,34 +825,9 @@ 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; -{ - /* Do not probe IRQ - pccard doesn't turn on the interrupt line */ - /* until bus_setup_intr */ -#ifdef PC98 - SET_FLAG(dev, COM_C_NOPROBE | SET_IFTYPE(COM_IF_MODEM_CARD)); -#else - SET_FLAG(dev, COM_C_NOPROBE); -#endif - - return (sioprobe(dev, 0)); -} - -static int -sio_pccard_attach(dev) - device_t dev; -{ - return (sioattach(dev, 0)); -} - /* - * sio_detach - unload the driver and clear the table. + * Unload the driver and clear the table. + * XXX this is mostly wrong. * XXX TODO: * This is usually called when the card is ejected, but * can be caused by a modunload of a controller driver. @@ -954,8 +835,8 @@ sio_pccard_attach(dev) * and ensure that any driver entry points such as * read and write do not hang. */ -static int -sio_pccard_detach(dev) +int +siodetach(dev) device_t dev; { struct com_s *com; @@ -985,126 +866,17 @@ sio_pccard_detach(dev) } else { if (com->ibuf != NULL) free(com->ibuf, M_DEVBUF); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); } - device_printf(dev, "unloaded\n"); return (0); } -#endif /* NCARD > 0 */ - -#if NPCI > 0 -struct pci_ids { - u_int32_t type; - const char *desc; - int rid; -}; - -static struct pci_ids pci_ids[] = { - { 0x100812b9, "3COM PCI FaxModem", 0x10 }, - { 0x2000131f, "CyberSerial (1-port) 16550", 0x10 }, - { 0x01101407, "Koutech IOFLEX-2S PCI Dual Port Serial", 0x10 }, - { 0x01111407, "Koutech IOFLEX-2S PCI Dual Port Serial", 0x10 }, - { 0x048011c1, "Lucent kermit based PCI Modem", 0x14 }, - { 0x95211415, "Oxford Semiconductor PCI Dual Port Serial", 0x10 }, - { 0x0000151f, "SmartLink 5634PCV SurfRider", 0x10 }, - /* { 0xXXXXXXXX, "Xircom Cardbus modem", 0x10 }, */ - { 0x00000000, NULL, 0 } -}; - -static int -sio_pci_attach(dev) - device_t dev; -{ - u_int32_t type; - struct pci_ids *id; - - type = pci_get_devid(dev); - id = pci_ids; - while (id->type && id->type != type) - id++; - if (id->desc == NULL) - return (ENXIO); - sio_pci_kludge_unit(dev); - return (sioattach(dev, id->rid)); -} -/* - * Don't cut and paste this to other drivers. It is a horrible kludge - * which will fail to work and also be unnecessary in future versions. - */ -static void -sio_pci_kludge_unit(dev) - device_t dev; -{ - devclass_t dc; - int err; - int start; - int unit; - - unit = 0; - start = 0; - while (resource_int_value("sio", unit, "port", &start) == 0 && - start > 0) - unit++; - if (device_get_unit(dev) < unit) { - dc = device_get_devclass(dev); - while (devclass_get_device(dc, unit)) - unit++; - device_printf(dev, "moving to sio%d\n", unit); - err = device_set_unit(dev, unit); /* EVIL DO NOT COPY */ - if (err) - device_printf(dev, "error moving device %d\n", err); - } -} - -static int -sio_pci_probe(dev) - device_t dev; -{ - u_int32_t type; - struct pci_ids *id; - - type = pci_get_devid(dev); - id = pci_ids; - while (id->type && id->type != type) - id++; - if (id->desc == NULL) - return (ENXIO); - device_set_desc(dev, id->desc); - return (sioprobe(dev, id->rid)); -} -#endif /* NPCI > 0 */ - -static struct isa_pnp_id sio_ids[] = { -#ifdef PC98 - {0x0100e4a5, "RSA-98III"}, -#endif - {0} -}; - - - -static int -sio_isa_probe(dev) - device_t dev; -{ -#ifdef PC98 - int logical_id; -#endif - /* Check isapnp ids */ - if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) - return (ENXIO); -#ifdef PC98 - logical_id = isa_get_logicalid(dev); - if (logical_id == 0x0100e4a5) /* RSA-98III */ - SET_FLAG(dev, SET_IFTYPE(COM_IF_RSA98III)); -#endif - return (sioprobe(dev, 0)); -} - -static int -sioprobe(dev, xrid) +int +sioprobe(dev, xrid, noprobe) device_t dev; int xrid; + int noprobe; { #if 0 static bool_t already_init; @@ -1167,12 +939,19 @@ sioprobe(dev, xrid) } #endif - com = device_get_softc(dev); + com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO); + if (com == NULL) + return (ENOMEM); + device_set_softc(dev, com); com->bst = rman_get_bustag(port); com->bsh = rman_get_bushandle(port); - if (atomic_cmpset_int(&sio_inited, 0, 1)) - mtx_init(&sio_lock, driver_name, MTX_SPIN); + while (sio_inited != 2) + if (atomic_cmpset_int(&sio_inited, 0, 1)) { + mtx_init(&sio_lock, sio_driver_name, (comconsole != -1) ? + MTX_SPIN | MTX_QUIET : MTX_SPIN); + atomic_store_rel_int(&sio_inited, 2); + } #if 0 /* @@ -1226,6 +1005,8 @@ sioprobe(dev, xrid) printf("sio%d: reserved for low-level i/o\n", device_get_unit(dev)); bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); return (ENXIO); } @@ -1237,6 +1018,8 @@ sioprobe(dev, xrid) */ if (pc98_check_if_type(dev, &iod) == -1) { bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); return (ENXIO); } if (iod.irq > 0) @@ -1276,6 +1059,10 @@ sioprobe(dev, xrid) result = 0; } bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + if (result) { + device_set_softc(dev, NULL); + free(com, M_DEVBUF); + } return result; } #endif /* PC98 */ @@ -1332,6 +1119,8 @@ sioprobe(dev, xrid) outb(iobase + rsa_frr, 0x00); if ((inb(iobase + rsa_srr) & 0x36) != 0x36) { bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); return (ENXIO); } outb(iobase + rsa_ier, 0x00); @@ -1353,6 +1142,8 @@ sioprobe(dev, xrid) printf("sio%d: irq configuration error\n", device_get_unit(dev)); bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); return (ENXIO); } outb((iobase & 0x00ff) | tmp, irqout); @@ -1452,7 +1243,7 @@ sioprobe(dev, xrid) * Some pcmcia cards have the "TXRDY bug", so we check everyone * for IIR_TXRDY implementation ( Palido 321s, DC-1S... ) */ - if (COM_NOPROBE(flags)) { + if (noprobe) { /* Reading IIR register twice */ for (fn = 0; fn < 2; fn ++) { DELAY(10000); @@ -1479,7 +1270,13 @@ sioprobe(dev, xrid) sio_setreg(com, com_cfcr, CFCR_8BITS); mtx_unlock_spin(&sio_lock); bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return (iobase == siocniobase ? 0 : result); + if (iobase == siocniobase) + result = 0; + if (result != 0) { + device_set_softc(dev, NULL); + free(com, M_DEVBUF); + } + return (result); } /* @@ -1564,7 +1361,13 @@ sioprobe(dev, xrid) break; } bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return (iobase == siocniobase ? 0 : result); + if (iobase == siocniobase) + result = 0; + if (result != 0) { + device_set_softc(dev, NULL); + free(com, M_DEVBUF); + } + return (result); } #ifdef COM_ESP @@ -1648,14 +1451,7 @@ espattach(com, esp_port) } #endif /* COM_ESP */ -static int -sio_isa_attach(dev) - device_t dev; -{ - return (sioattach(dev, 0)); -} - -static int +int sioattach(dev, xrid) device_t dev; int xrid; @@ -4166,13 +3962,14 @@ void siogdbputc __P((int c)); #else static cn_probe_t siocnprobe; static cn_init_t siocninit; +static cn_term_t siocnterm; #endif static cn_checkc_t siocncheckc; static cn_getc_t siocngetc; static cn_putc_t siocnputc; #ifndef __alpha__ -CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, +CONS_DRIVER(sio, siocnprobe, siocninit, siocnterm, siocngetc, siocncheckc, siocnputc, NULL); #endif @@ -4424,6 +4221,13 @@ siocninit(cp) comconsole = DEV_TO_UNIT(cp->cn_dev); } +static void +siocnterm(cp) + struct consdev *cp; +{ + comconsole = -1; +} + #endif #ifdef __alpha__ @@ -4627,18 +4431,6 @@ siogdbputc(c) } #endif -DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0); -#ifndef PC98 -DRIVER_MODULE(sio, acpi, sio_isa_driver, sio_devclass, 0, 0); -#endif -#if NCARD > 0 -DRIVER_MODULE(sio, pccard, sio_pccard_driver, sio_devclass, 0, 0); -#endif -#if NPCI > 0 -DRIVER_MODULE(sio, pci, sio_pci_driver, sio_devclass, 0, 0); -DRIVER_MODULE(sio, cardbus, sio_pci_driver, sio_devclass, 0, 0); -#endif - #ifdef PC98 /* * pc98 local function diff --git a/sys/pc98/cbus/sio_cbus.c b/sys/pc98/cbus/sio_cbus.c new file mode 100644 index 00000000000..6f9e3114837 --- /dev/null +++ b/sys/pc98/cbus/sio_cbus.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2001 Yoshihiro TAKAHASHI. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +static int sio_isa_attach __P((device_t dev)); +static int sio_isa_probe __P((device_t dev)); + +static device_method_t sio_isa_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, sio_isa_probe), + DEVMETHOD(device_attach, sio_isa_attach), + + { 0, 0 } +}; + +static driver_t sio_isa_driver = { + sio_driver_name, + sio_isa_methods, + 0, +}; + +static struct isa_pnp_id sio_ids[] = { + {0x0100e4a5, "RSA-98III"}, + {0} +}; + +static int +sio_isa_probe(dev) + device_t dev; +{ +#ifdef PC98 + int logical_id; +#endif + /* Check isapnp ids */ + if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) + return (ENXIO); +#ifdef PC98 + logical_id = isa_get_logicalid(dev); + switch (logical_id) { + case 0x0100e4a5: /* RSA-98III */ + SET_FLAG(dev, SET_IFTYPE(COM_IF_RSA98III)); + break; + } +#endif + return (sioprobe(dev, 0, 0)); +} + +static int +sio_isa_attach(dev) + device_t dev; +{ + return (sioattach(dev, 0)); +} + +DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0); diff --git a/sys/pc98/pc98/pc98.h b/sys/pc98/pc98/pc98.h index 1dc36d60094..15226d3f3b8 100644 --- a/sys/pc98/pc98/pc98.h +++ b/sys/pc98/pc98/pc98.h @@ -110,7 +110,6 @@ #define IO_ASCSIZE 5 /* AmiScan GI1904-based hand scanner */ #define IO_CGASIZE 16 /* CGA controllers */ -#define IO_COMSIZE 8 /* 8250, 16X50 com controllers (4?) */ #define IO_DMASIZE 16 /* 8237 DMA controllers */ #define IO_DPGSIZE 32 /* 74LS612 DMA page registers */ #define IO_EISASIZE 4096 /* EISA controllers */ diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c index cc231ddd09b..cf1b03a52ce 100644 --- a/sys/pc98/pc98/sio.c +++ b/sys/pc98/pc98/sio.c @@ -39,8 +39,6 @@ #include "opt_compat.h" #include "opt_ddb.h" #include "opt_sio.h" -#include "card.h" -#include "pci.h" /* * Serial driver, based on 386BSD-0.1 com driver. @@ -114,30 +112,6 @@ * modified for 8251(FIFO) by Seigo TANIMURA */ -#ifdef PC98 -#define COM_IF_INTERNAL 0x00 -#define COM_IF_PC9861K_1 0x01 -#define COM_IF_PC9861K_2 0x02 -#define COM_IF_IND_SS_1 0x03 -#define COM_IF_IND_SS_2 0x04 -#define COM_IF_PIO9032B_1 0x05 -#define COM_IF_PIO9032B_2 0x06 -#define COM_IF_B98_01_1 0x07 -#define COM_IF_B98_01_2 0x08 -#define COM_IF_END1 COM_IF_B98_01_2 -#define COM_IF_RSA98 0x10 /* same as COM_IF_NS16550 */ -#define COM_IF_NS16550 0x11 -#define COM_IF_SECOND_CCU 0x12 /* same as COM_IF_NS16550 */ -#define COM_IF_MC16550II 0x13 -#define COM_IF_MCRS98 0x14 /* same as COM_IF_MC16550II */ -#define COM_IF_RSB3000 0x15 -#define COM_IF_RSB384 0x16 -#define COM_IF_MODEM_CARD 0x17 -#define COM_IF_RSA98III 0x18 -#define COM_IF_ESP98 0x19 -#define COM_IF_END2 COM_IF_ESP98 -#endif /* PC98 */ - #include #include #include @@ -160,21 +134,17 @@ #include #include -#ifdef PC98 -#include -#include -#else -#include -#endif #include -#if NPCI > 0 -#include -#include -#endif #include #include +#include + +#ifdef PC98 +#include +#include +#endif #ifdef COM_ESP #include @@ -399,8 +369,6 @@ struct com_s { #ifdef COM_ESP static int espattach __P((struct com_s *com, Port_t esp_port)); #endif -static int sioattach __P((device_t dev, int rid)); -static int sio_isa_attach __P((device_t dev)); static timeout_t siobusycheck; static timeout_t siodtrwakeup; @@ -411,8 +379,6 @@ static void siointr __P((void *arg)); static int commctl __P((struct com_s *com, int bits, int how)); static int comparam __P((struct tty *tp, struct termios *t)); static void siopoll __P((void *)); -static int sioprobe __P((device_t dev, int xrid)); -static int sio_isa_probe __P((device_t dev)); static void siosettimeout __P((void)); static int siosetwater __P((struct com_s *com, speed_t speed)); static void comstart __P((struct tty *tp)); @@ -421,73 +387,14 @@ static timeout_t comwakeup; static void disc_optim __P((struct tty *tp, struct termios *t, struct com_s *com)); -#if NCARD > 0 -static int sio_pccard_attach __P((device_t dev)); -static int sio_pccard_detach __P((device_t dev)); -static int sio_pccard_probe __P((device_t dev)); -#endif /* NCARD > 0 */ - -#if NPCI > 0 -static int sio_pci_attach __P((device_t dev)); -static void sio_pci_kludge_unit __P((device_t dev)); -static int sio_pci_probe __P((device_t dev)); -#endif /* NPCI > 0 */ - -static char driver_name[] = "sio"; +char sio_driver_name[] = "sio"; static struct mtx sio_lock; static int sio_inited; /* table and macro for fast conversion from a unit number to its com struct */ -static devclass_t sio_devclass; +devclass_t sio_devclass; #define com_addr(unit) ((struct com_s *) \ - devclass_get_softc(sio_devclass, unit)) - -static device_method_t sio_isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_isa_probe), - DEVMETHOD(device_attach, sio_isa_attach), - - { 0, 0 } -}; - -static driver_t sio_isa_driver = { - driver_name, - sio_isa_methods, - sizeof(struct com_s), -}; - -#if NCARD > 0 -static device_method_t sio_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_pccard_probe), - DEVMETHOD(device_attach, sio_pccard_attach), - DEVMETHOD(device_detach, sio_pccard_detach), - - { 0, 0 } -}; - -static driver_t sio_pccard_driver = { - driver_name, - sio_pccard_methods, - sizeof(struct com_s), -}; -#endif /* NCARD > 0 */ - -#if NPCI > 0 -static device_method_t sio_pci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_pci_probe), - DEVMETHOD(device_attach, sio_pci_attach), - - { 0, 0 } -}; - -static driver_t sio_pci_driver = { - driver_name, - sio_pci_methods, - sizeof(struct com_s), -}; -#endif /* NPCI > 0 */ + devclass_get_softc(sio_devclass, unit)) /* XXX */ static d_open_t sioopen; static d_close_t sioclose; @@ -505,7 +412,7 @@ static struct cdevsw sio_cdevsw = { /* poll */ ttypoll, /* mmap */ nommap, /* strategy */ nostrategy, - /* name */ driver_name, + /* name */ sio_driver_name, /* maj */ CDEV_MAJOR, /* dump */ nodump, /* psize */ nopsize, @@ -549,8 +456,6 @@ static int sysclock; #define PC98_CHECK_MODEM_INTERVAL (hz/10) #define DCD_OFF_TOLERANCE 2 #define DCD_ON_RECOGNITION 2 -#define GET_IFTYPE(flags) ((flags >> 24) & 0x1f) -#define SET_IFTYPE(type) (type << 24) #define IS_8251(if_type) (!(if_type & 0x10)) #define COM1_EXT_CLOCK 0x40000 @@ -842,6 +747,7 @@ struct { #ifdef PC98 /* XXX configure this properly. */ +/* XXX quite broken for new-bus. */ static Port_t likely_com_ports[] = { 0, 0xb0, 0xb1, 0 }; static Port_t likely_esp_ports[] = { 0xc0d0, 0 }; @@ -919,34 +825,9 @@ 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; -{ - /* Do not probe IRQ - pccard doesn't turn on the interrupt line */ - /* until bus_setup_intr */ -#ifdef PC98 - SET_FLAG(dev, COM_C_NOPROBE | SET_IFTYPE(COM_IF_MODEM_CARD)); -#else - SET_FLAG(dev, COM_C_NOPROBE); -#endif - - return (sioprobe(dev, 0)); -} - -static int -sio_pccard_attach(dev) - device_t dev; -{ - return (sioattach(dev, 0)); -} - /* - * sio_detach - unload the driver and clear the table. + * Unload the driver and clear the table. + * XXX this is mostly wrong. * XXX TODO: * This is usually called when the card is ejected, but * can be caused by a modunload of a controller driver. @@ -954,8 +835,8 @@ sio_pccard_attach(dev) * and ensure that any driver entry points such as * read and write do not hang. */ -static int -sio_pccard_detach(dev) +int +siodetach(dev) device_t dev; { struct com_s *com; @@ -985,126 +866,17 @@ sio_pccard_detach(dev) } else { if (com->ibuf != NULL) free(com->ibuf, M_DEVBUF); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); } - device_printf(dev, "unloaded\n"); return (0); } -#endif /* NCARD > 0 */ - -#if NPCI > 0 -struct pci_ids { - u_int32_t type; - const char *desc; - int rid; -}; - -static struct pci_ids pci_ids[] = { - { 0x100812b9, "3COM PCI FaxModem", 0x10 }, - { 0x2000131f, "CyberSerial (1-port) 16550", 0x10 }, - { 0x01101407, "Koutech IOFLEX-2S PCI Dual Port Serial", 0x10 }, - { 0x01111407, "Koutech IOFLEX-2S PCI Dual Port Serial", 0x10 }, - { 0x048011c1, "Lucent kermit based PCI Modem", 0x14 }, - { 0x95211415, "Oxford Semiconductor PCI Dual Port Serial", 0x10 }, - { 0x0000151f, "SmartLink 5634PCV SurfRider", 0x10 }, - /* { 0xXXXXXXXX, "Xircom Cardbus modem", 0x10 }, */ - { 0x00000000, NULL, 0 } -}; - -static int -sio_pci_attach(dev) - device_t dev; -{ - u_int32_t type; - struct pci_ids *id; - - type = pci_get_devid(dev); - id = pci_ids; - while (id->type && id->type != type) - id++; - if (id->desc == NULL) - return (ENXIO); - sio_pci_kludge_unit(dev); - return (sioattach(dev, id->rid)); -} -/* - * Don't cut and paste this to other drivers. It is a horrible kludge - * which will fail to work and also be unnecessary in future versions. - */ -static void -sio_pci_kludge_unit(dev) - device_t dev; -{ - devclass_t dc; - int err; - int start; - int unit; - - unit = 0; - start = 0; - while (resource_int_value("sio", unit, "port", &start) == 0 && - start > 0) - unit++; - if (device_get_unit(dev) < unit) { - dc = device_get_devclass(dev); - while (devclass_get_device(dc, unit)) - unit++; - device_printf(dev, "moving to sio%d\n", unit); - err = device_set_unit(dev, unit); /* EVIL DO NOT COPY */ - if (err) - device_printf(dev, "error moving device %d\n", err); - } -} - -static int -sio_pci_probe(dev) - device_t dev; -{ - u_int32_t type; - struct pci_ids *id; - - type = pci_get_devid(dev); - id = pci_ids; - while (id->type && id->type != type) - id++; - if (id->desc == NULL) - return (ENXIO); - device_set_desc(dev, id->desc); - return (sioprobe(dev, id->rid)); -} -#endif /* NPCI > 0 */ - -static struct isa_pnp_id sio_ids[] = { -#ifdef PC98 - {0x0100e4a5, "RSA-98III"}, -#endif - {0} -}; - - - -static int -sio_isa_probe(dev) - device_t dev; -{ -#ifdef PC98 - int logical_id; -#endif - /* Check isapnp ids */ - if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) - return (ENXIO); -#ifdef PC98 - logical_id = isa_get_logicalid(dev); - if (logical_id == 0x0100e4a5) /* RSA-98III */ - SET_FLAG(dev, SET_IFTYPE(COM_IF_RSA98III)); -#endif - return (sioprobe(dev, 0)); -} - -static int -sioprobe(dev, xrid) +int +sioprobe(dev, xrid, noprobe) device_t dev; int xrid; + int noprobe; { #if 0 static bool_t already_init; @@ -1167,12 +939,19 @@ sioprobe(dev, xrid) } #endif - com = device_get_softc(dev); + com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO); + if (com == NULL) + return (ENOMEM); + device_set_softc(dev, com); com->bst = rman_get_bustag(port); com->bsh = rman_get_bushandle(port); - if (atomic_cmpset_int(&sio_inited, 0, 1)) - mtx_init(&sio_lock, driver_name, MTX_SPIN); + while (sio_inited != 2) + if (atomic_cmpset_int(&sio_inited, 0, 1)) { + mtx_init(&sio_lock, sio_driver_name, (comconsole != -1) ? + MTX_SPIN | MTX_QUIET : MTX_SPIN); + atomic_store_rel_int(&sio_inited, 2); + } #if 0 /* @@ -1226,6 +1005,8 @@ sioprobe(dev, xrid) printf("sio%d: reserved for low-level i/o\n", device_get_unit(dev)); bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); return (ENXIO); } @@ -1237,6 +1018,8 @@ sioprobe(dev, xrid) */ if (pc98_check_if_type(dev, &iod) == -1) { bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); return (ENXIO); } if (iod.irq > 0) @@ -1276,6 +1059,10 @@ sioprobe(dev, xrid) result = 0; } bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + if (result) { + device_set_softc(dev, NULL); + free(com, M_DEVBUF); + } return result; } #endif /* PC98 */ @@ -1332,6 +1119,8 @@ sioprobe(dev, xrid) outb(iobase + rsa_frr, 0x00); if ((inb(iobase + rsa_srr) & 0x36) != 0x36) { bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); return (ENXIO); } outb(iobase + rsa_ier, 0x00); @@ -1353,6 +1142,8 @@ sioprobe(dev, xrid) printf("sio%d: irq configuration error\n", device_get_unit(dev)); bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + device_set_softc(dev, NULL); + free(com, M_DEVBUF); return (ENXIO); } outb((iobase & 0x00ff) | tmp, irqout); @@ -1452,7 +1243,7 @@ sioprobe(dev, xrid) * Some pcmcia cards have the "TXRDY bug", so we check everyone * for IIR_TXRDY implementation ( Palido 321s, DC-1S... ) */ - if (COM_NOPROBE(flags)) { + if (noprobe) { /* Reading IIR register twice */ for (fn = 0; fn < 2; fn ++) { DELAY(10000); @@ -1479,7 +1270,13 @@ sioprobe(dev, xrid) sio_setreg(com, com_cfcr, CFCR_8BITS); mtx_unlock_spin(&sio_lock); bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return (iobase == siocniobase ? 0 : result); + if (iobase == siocniobase) + result = 0; + if (result != 0) { + device_set_softc(dev, NULL); + free(com, M_DEVBUF); + } + return (result); } /* @@ -1564,7 +1361,13 @@ sioprobe(dev, xrid) break; } bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return (iobase == siocniobase ? 0 : result); + if (iobase == siocniobase) + result = 0; + if (result != 0) { + device_set_softc(dev, NULL); + free(com, M_DEVBUF); + } + return (result); } #ifdef COM_ESP @@ -1648,14 +1451,7 @@ espattach(com, esp_port) } #endif /* COM_ESP */ -static int -sio_isa_attach(dev) - device_t dev; -{ - return (sioattach(dev, 0)); -} - -static int +int sioattach(dev, xrid) device_t dev; int xrid; @@ -4166,13 +3962,14 @@ void siogdbputc __P((int c)); #else static cn_probe_t siocnprobe; static cn_init_t siocninit; +static cn_term_t siocnterm; #endif static cn_checkc_t siocncheckc; static cn_getc_t siocngetc; static cn_putc_t siocnputc; #ifndef __alpha__ -CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, +CONS_DRIVER(sio, siocnprobe, siocninit, siocnterm, siocngetc, siocncheckc, siocnputc, NULL); #endif @@ -4424,6 +4221,13 @@ siocninit(cp) comconsole = DEV_TO_UNIT(cp->cn_dev); } +static void +siocnterm(cp) + struct consdev *cp; +{ + comconsole = -1; +} + #endif #ifdef __alpha__ @@ -4627,18 +4431,6 @@ siogdbputc(c) } #endif -DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0); -#ifndef PC98 -DRIVER_MODULE(sio, acpi, sio_isa_driver, sio_devclass, 0, 0); -#endif -#if NCARD > 0 -DRIVER_MODULE(sio, pccard, sio_pccard_driver, sio_devclass, 0, 0); -#endif -#if NPCI > 0 -DRIVER_MODULE(sio, pci, sio_pci_driver, sio_devclass, 0, 0); -DRIVER_MODULE(sio, cardbus, sio_pci_driver, sio_devclass, 0, 0); -#endif - #ifdef PC98 /* * pc98 local function diff --git a/sys/pc98/pc98/sio_cbus.c b/sys/pc98/pc98/sio_cbus.c new file mode 100644 index 00000000000..6f9e3114837 --- /dev/null +++ b/sys/pc98/pc98/sio_cbus.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2001 Yoshihiro TAKAHASHI. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +static int sio_isa_attach __P((device_t dev)); +static int sio_isa_probe __P((device_t dev)); + +static device_method_t sio_isa_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, sio_isa_probe), + DEVMETHOD(device_attach, sio_isa_attach), + + { 0, 0 } +}; + +static driver_t sio_isa_driver = { + sio_driver_name, + sio_isa_methods, + 0, +}; + +static struct isa_pnp_id sio_ids[] = { + {0x0100e4a5, "RSA-98III"}, + {0} +}; + +static int +sio_isa_probe(dev) + device_t dev; +{ +#ifdef PC98 + int logical_id; +#endif + /* Check isapnp ids */ + if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) + return (ENXIO); +#ifdef PC98 + logical_id = isa_get_logicalid(dev); + switch (logical_id) { + case 0x0100e4a5: /* RSA-98III */ + SET_FLAG(dev, SET_IFTYPE(COM_IF_RSA98III)); + break; + } +#endif + return (sioprobe(dev, 0, 0)); +} + +static int +sio_isa_attach(dev) + device_t dev; +{ + return (sioattach(dev, 0)); +} + +DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0); -- 2.45.2