diff options
| author | Warner Losh <imp@FreeBSD.org> | 2000-04-01 06:14:21 +0000 |
|---|---|---|
| committer | Warner Losh <imp@FreeBSD.org> | 2000-04-01 06:14:21 +0000 |
| commit | b6f6dacdd3e80c49319b3f8625c8f575ec0a1c59 (patch) | |
| tree | 9a5a00669fb78d92eca085322ff8fd5bfece04b1 /sys/dev/sio/sio.c | |
| parent | ce73953a1eb3727d335775b39eea94fa28ec696b (diff) | |
Notes
Diffstat (limited to 'sys/dev/sio/sio.c')
| -rw-r--r-- | sys/dev/sio/sio.c | 136 |
1 files changed, 122 insertions, 14 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index bdccf3ded5a0..395b5b9b2b11 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -40,6 +40,7 @@ #include "opt_ddb.h" #include "opt_sio.h" #include "card.h" +#include "pci.h" #include "sio.h" /* @@ -73,6 +74,10 @@ #include <isa/isareg.h> #include <isa/isavar.h> +#if NPCI > 0 +#include <pci/pcireg.h> +#include <pci/pcivar.h> +#endif #include <machine/lock.h> #include <machine/clock.h> @@ -278,7 +283,7 @@ 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)); +static int sioattach __P((device_t dev, int rid)); static int sio_isa_attach __P((device_t dev)); static timeout_t siobusycheck; @@ -290,7 +295,7 @@ 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 swihand_t siopoll; -static int sioprobe __P((device_t dev)); +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)); @@ -306,6 +311,12 @@ 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"; /* table and macro for fast conversion from a unit number to its com struct */ @@ -342,7 +353,23 @@ static driver_t sio_pccard_driver = { sio_pccard_methods, sizeof(struct com_s), }; -#endif (NCARD > 0) +#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 */ static d_open_t sioopen; static d_close_t sioclose; @@ -485,14 +512,14 @@ sio_pccard_probe(dev) /* until bus_setup_intr */ SET_FLAG(dev, COM_C_NOPROBE); - return (sioprobe(dev)); + return (sioprobe(dev, 0)); } static int sio_pccard_attach(dev) device_t dev; { - return (sioattach(dev)); + return (sioattach(dev, 0)); } /* @@ -541,6 +568,82 @@ sio_pccard_detach(dev) } #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 }, + { 0x048011c1, "ActionTec 56k FAX PCI Modem", 0x14 }, + { 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[] = { {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ @@ -615,12 +718,13 @@ sio_isa_probe(dev) /* Check isapnp ids */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) return (ENXIO); - return (sioprobe(dev)); + return (sioprobe(dev, 0)); } static int -sioprobe(dev) +sioprobe(dev, xrid) device_t dev; + int xrid; { #if 0 static bool_t already_init; @@ -639,7 +743,7 @@ sioprobe(dev) int rid; struct resource *port; - rid = 0; + rid = xrid; port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, IO_COMSIZE, RF_ACTIVE); if (!port) @@ -968,12 +1072,13 @@ static int sio_isa_attach(dev) device_t dev; { - return (sioattach(dev)); + return (sioattach(dev, 0)); } static int -sioattach(dev) +sioattach(dev, xrid) device_t dev; + int xrid; { struct com_s *com; #ifdef COM_ESP @@ -986,7 +1091,7 @@ sioattach(dev) struct resource *port; int ret; - rid = 0; + rid = xrid; port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, IO_COMSIZE, RF_ACTIVE); if (!port) @@ -2765,7 +2870,7 @@ siocngetspeed(iobase, table) if (table->sp_code == code) return (table->sp_speed); - return 0; /* didn't match anything sane */ + return (0); /* didn't match anything sane */ } static void @@ -2986,7 +3091,7 @@ siocnattach(port, speed) splx(s); cn_tab = &sio_consdev; - return 0; + return (0); } int @@ -3023,7 +3128,7 @@ siogdbattach(port, speed) siocnopen(&sp, siogdbiobase, gdbdefaultrate); splx(s); - return 0; + return (0); } #endif @@ -3144,3 +3249,6 @@ DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0); #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); +#endif |
