Date: Tue, 24 Dec 2002 15:18:18 -0800 (PST) From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 22723 for review Message-ID: <200212242318.gBONIIEl022652@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=22723 Change 22723 by marcel@marcel_vaio on 2002/12/24 15:17:56 Revise the revised interface to sioprobe/sioattach. In order to have a centralized function that handles detachment, we need to have the rid, type and resource pointer for the address of the UART. We now store it in the softc. Consequently, we don't have to do all the work in the bus specific front-ends. As such, the bus specific front-ends only have to define the addr_rid, addr_type and addr_res fields and sioprobe will do the rest. Note that the allocation of the resource is kept in the bus specific front-end because we may need to try a couple of times before it works (see sio_isa.c). The bus specific attachment routines are simple stubs again. The same applies to the detachment routines. Have the softc point back to the device to de-weird-ify the siodescribe prototype. Remove the no_irq flag for now. It was only used to initialize the poll field. We can use irq_res for that as well. Some other cleanups like removal of unused fields and reordering of the bus specific routines. Only sio_ebus.c has not been verified to at least compile. Affected files ... .. //depot/projects/ia64/sys/dev/sio/sio.c#27 edit .. //depot/projects/ia64/sys/dev/sio/sio_ebus.c#6 edit .. //depot/projects/ia64/sys/dev/sio/sio_isa.c#13 edit .. //depot/projects/ia64/sys/dev/sio/sio_pccard.c#8 edit .. //depot/projects/ia64/sys/dev/sio/sio_pci.c#12 edit .. //depot/projects/ia64/sys/dev/sio/sio_puc.c#7 edit .. //depot/projects/ia64/sys/dev/sio/siovar.h#13 edit Differences ... ==== //depot/projects/ia64/sys/dev/sio/sio.c#27 (text+ko) ==== @@ -450,10 +450,11 @@ ttwakeup(com->tp); ttwwakeup(com->tp); } - if (com->irqres) { - bus_teardown_intr(dev, com->irqres, com->cookie); - bus_release_resource(dev, SYS_RES_IRQ, 0, com->irqres); + if (com->irq_res) { + bus_teardown_intr(dev, com->irq_res, com->irq_cookie); + bus_release_resource(dev, SYS_RES_IRQ, 0, com->irq_res); } + bus_release_resource(dev, com->addr_type, com->addr_rid, com->addr_res); for (i = 0 ; i < 6; i++) destroy_dev(com->devs[i]); if (com->ibuf != NULL) @@ -476,17 +477,38 @@ } com = (struct com_s *)device_get_softc(dev); + com->bsh = rman_get_bushandle(com->addr_res); + com->bst = rman_get_bustag(com->addr_res); - /* Check if we're probing what could be the console. */ + /* + * Check if we're probing what could be the console. If so, we'll + * switch to the static sio_console struct so that if we have a + * serial console we have all the state information. We assume that + * at this time the bus specific front-ends only defined addr_type, + * addr_rid and addr_res. + */ if (com->bst == sio_console.bst && com->bsh == sio_console.bsh) { + sio_console.addr_res = com->addr_res; + sio_console.addr_rid = com->addr_rid; + sio_console.addr_type = com->addr_type; + device_set_softc(dev, &sio_console); com = &sio_console; - device_set_softc(dev, com); } + com->dev = dev; + + /* + * Perform rudimentary sanity checking and specific initialization + * for non-console devices. We expect that the console device has + * had the sanity checking and that the fields we initialize here + * are set correctly for the console. + */ if (com->consdev == NULL) { - /* Perform rudimentary sanity checking. */ - if (sioprobe1(com)) + if (sioprobe1(com)) { + bus_release_resource(dev, com->addr_type, + com->addr_rid, com->addr_res); return (ENXIO); + } if (com->rclk == 0) com->rclk = DEFAULT_RCLK; @@ -502,9 +524,14 @@ if (COM_LLCONSOLE(flags)) { device_printf(dev, "reserved for low-level i/o\n"); + /* + * Don't release the address resource! We don't want it to be + * taken by other drivers. + */ return (ENXIO); } + bus_release_resource(dev, com->addr_type, com->addr_rid, com->addr_res); return (0); } @@ -516,6 +543,13 @@ u_int flags; com = device_get_softc(dev); + + /* Assume addr_rid and addr_type are still valid (set by probe). */ + com->addr_res = bus_alloc_resource(dev, com->addr_type, &com->addr_rid, + 0, ~0, 8, RF_ACTIVE); + if (com->addr_res == NULL) + return (ENXIO); + flags = device_get_flags(dev); unit = device_get_unit(dev); @@ -543,7 +577,6 @@ com->unit = unit; com->dtr_wait = 3 * hz; com->loses_outints = COM_LOSESOUTINTS(flags) != 0; - com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0; com->obufs[0].l_head = com->obuf1; com->obufs[1].l_head = com->obuf2; @@ -574,6 +607,8 @@ if (siosetwater(com, com->it_in.c_ispeed) != 0) { mtx_unlock_spin(&sio_lock); + bus_release_resource(dev, com->addr_type, com->addr_rid, + com->addr_res); return (ENOMEM); } @@ -590,6 +625,7 @@ swi_add(&clk_ithd, "tty:sio", siopoll, NULL, SWI_TTY, 0, &sio_slow_ih); } + minorbase = UNIT_TO_MINOR(unit); com->devs[0] = make_dev(&sio_cdevsw, minorbase, UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit); @@ -605,37 +641,43 @@ com->devs[5] = make_dev(&sio_cdevsw, minorbase | CALLOUT_MASK | CONTROL_LOCK_STATE, UID_UUCP, GID_DIALER, 0660, "cuala%r", unit); + com->flags = flags; com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; pps_init(&com->pps); rid = 0; - com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, + com->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, RF_ACTIVE); - if (com->irqres) { - ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, - INTR_TYPE_TTY | INTR_FAST, - siointr, com, &com->cookie); + if (com->irq_res) { + ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irq_res, + INTR_TYPE_TTY | INTR_FAST, siointr, com, &com->irq_cookie); if (ret) { ret = BUS_SETUP_INTR(device_get_parent(dev), dev, - com->irqres, INTR_TYPE_TTY, - siointr, com, &com->cookie); + com->irq_res, INTR_TYPE_TTY, siointr, com, + &com->irq_cookie); if (ret == 0) - device_printf(dev, "unable to activate interrupt in fast mode - using normal mode\n"); + device_printf(dev, + "unable to activate interrupt in fast mode - using normal mode\n"); } - if (ret) + if (ret) { device_printf(dev, "could not activate interrupt\n"); -#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \ - defined(ALT_BREAK_TO_DEBUGGER)) - /* - * Enable interrupts for early break-to-debugger support - * on the console. - */ - if (ret == 0 && com->consdev != NULL) - sio_setreg(com, com_ier, IER_ERXRDY | IER_ERLS | - IER_EMSC); + bus_release_resource(dev, SYS_RES_IRQ, rid, + com->irq_res); + com->irq_res = NULL; + } + } + +#if defined(DDB) +#if defined(BREAK_TO_DEBUGGER) || defined(ALT_BREAK_TO_DEBUGGER) + /* + * Enable interrupts for early break-to-debugger support + * on the console. + */ + if (com->irq_res != NULL && com->consdev != NULL) + sio_setreg(com, com_ier, IER_ERXRDY | IER_ERLS | IER_EMSC); #endif - } +#endif /* DDB */ return (0); } @@ -721,7 +763,7 @@ tp->t_termios = mynor & CALLOUT_MASK ? com->it_out : com->it_in; (void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET); - com->poll = com->no_irq; + com->poll = (com->irq_res == NULL) ? 1 : 0; com->poll_output = com->loses_outints; ++com->wopeners; error = comparam(tp, &tp->t_termios); ==== //depot/projects/ia64/sys/dev/sio/sio_ebus.c#6 (text+ko) ==== @@ -61,8 +61,6 @@ sizeof(struct com_s), }; -DRIVER_MODULE(sio, ebus, sio_ebus_driver, sio_devclass, 0, 0); - /* Needed for EBus attach and sparc64 console support */ char *sio_ofw_names[] = { "serial", @@ -94,13 +92,10 @@ } static int -sio_ebus_probe(dev) - device_t dev; +sio_ebus_probe(device_t dev) { struct com_s *com; - struct resource *res; char *n; - int error, rid; n = ebus_get_name(dev); if (!sio_ofw_inlist(n, sio_ofw_names) && (strcmp(n, "serial") != 0 || @@ -108,34 +103,20 @@ return (ENXIO); com = device_get_softc(dev); - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 8, - RF_ACTIVE); - if (res == NULL) + com->addr_rid = 0; + com->addr_type = SYS_RES_IOPORT; + com->addr_res = bus_alloc_resource(dev, com->addr_type, &com->addr_rid, + 0, ~0, 8, RF_ACTIVE); + if (com->addr_res == NULL) return (ENXIO); - com->bsh = rman_get_bushandle(res); - com->bst = rman_get_bustag(res); - error = sioprobe(dev); - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - return (error); + return (sioprobe(dev)); } static int -sio_ebus_attach(dev) - device_t dev; +sio_ebus_attach(device_t dev) { - struct com_s *com; - struct resource *res; - int error, rid; - com = device_get_softc(dev); - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 8, - RF_ACTIVE); - if (res == NULL) - return (ENXIO); - error = sioattach(dev); - if (error) - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - return (error); + return (sioattach(dev)); } + +DRIVER_MODULE(sio, ebus, sio_ebus_driver, sio_devclass, 0, 0); ==== //depot/projects/ia64/sys/dev/sio/sio_isa.c#13 (text+ko) ==== @@ -149,57 +149,36 @@ {0} }; -static struct resource * -sio_isa_alloc(device_t dev, int *sp, int *rid) -{ - struct resource *res; - - *rid = 0; - *sp = SYS_RES_IOPORT; - res = bus_alloc_resource(dev, *sp, rid, 0, ~0, 8, RF_ACTIVE); - if (res == NULL) { - *rid = 0; - *sp = SYS_RES_MEMORY; - res = bus_alloc_resource(dev, *sp, rid, 0, ~0, 8, RF_ACTIVE); - } - return (res); -} - static int sio_isa_probe(device_t dev) { struct com_s *com; - struct resource *res; - int error, rid, space; /* Check isapnp ids */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) return (ENXIO); - res = sio_isa_alloc(dev, &space, &rid); - if (res == NULL) - return (ENXIO); com = device_get_softc(dev); - com->bsh = rman_get_bushandle(res); - com->bst = rman_get_bustag(res); - error = sioprobe(dev); - bus_release_resource(dev, space, rid, res); - return (error); + com->addr_rid = 0; + com->addr_type = SYS_RES_IOPORT; + com->addr_res = bus_alloc_resource(dev, com->addr_type, &com->addr_rid, + 0, ~0, 8, RF_ACTIVE); + if (com->addr_res == NULL) { + com->addr_rid = 0; + com->addr_type = SYS_RES_MEMORY; + com->addr_res = bus_alloc_resource(dev, com->addr_type, + &com->addr_rid, 0, ~0, 8, RF_ACTIVE); + if (com->addr_res == NULL) + return (ENXIO); + } + return (sioprobe(dev)); } static int sio_isa_attach(device_t dev) { - struct resource *res; - int error, rid, space; - res = sio_isa_alloc(dev, &space, &rid); - if (res == NULL) - return (ENXIO); - error = sioattach(dev); - if (error) - bus_release_resource(dev, space, rid, res); - return (error); + return (sioattach(dev)); } DRIVER_MODULE(sio, acpi, sio_isa_driver, sio_devclass, 0, 0); ==== //depot/projects/ia64/sys/dev/sio/sio_pccard.c#8 (text+ko) ==== @@ -37,6 +37,7 @@ #include <machine/bus.h> #include <machine/resource.h> #include <sys/timepps.h> +#include <sys/rman.h> #include <dev/pccard/pccardreg.h> #include <dev/pccard/pccardvar.h> @@ -90,55 +91,36 @@ } static int -sio_pccard_probe(dev) - device_t dev; +sio_pccard_probe(device_t dev) { struct com_s *com; - struct resource *res; - int error, rid; #ifdef PC98 SET_FLAG(dev, SET_IFTYPE(COM_IF_MODEM_CARD)); #endif com = device_get_softc(dev); - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 8, - RF_ACTIVE); - if (res == NULL) + com->addr_rid = 0; + com->addr_type = SYS_RES_IOPORT; + com->addr_res = bus_alloc_resource(dev, com->addr_type, &com->addr_rid, + 0, ~0, 8, RF_ACTIVE); + if (com->addr_res == NULL) return (ENXIO); - com->bsh = rman_get_bushandle(res); - com->bst = rman_get_bustag(res); - error = sioprobe(dev); - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - return (error); + return (sioprobe(dev)); } static int -sio_pccard_attach(dev) - device_t dev; +sio_pccard_attach(device_t dev) { - struct com_s *com; - struct resource *res; - int error, rid; - com = device_get_softc(dev); - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 8, - RF_ACTIVE); - if (res == NULL) - return (ENXIO); - error = sioattach(dev); - if (error) - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - return (error); + return (sioattach(dev)); } static int -sio_pccard_detach(dev) - device_t dev; +sio_pccard_detach(device_t dev) { - /* XXX broken */ + + return (siodetach(dev)); } DRIVER_MODULE(sio, pccard, sio_pccard_driver, sio_devclass, 0, 0); ==== //depot/projects/ia64/sys/dev/sio/sio_pci.c#12 (text+ko) ==== @@ -97,50 +97,35 @@ } static int -sio_pci_attach(device_t dev) +sio_pci_probe(device_t dev) { struct com_s *com; struct pci_ids *id; - struct resource *res; - int error, rid, space; + +#ifdef PC98 + SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550)); +#endif + id = pci_id(dev); + if (id == NULL) + return (ENXIO); + if (id->desc) + device_set_desc(dev, id->desc); com = device_get_softc(dev); - id = pci_id(dev); - rid = (id->rid >= 0) ? id->rid : -id->rid; - space = (id->rid >= 0) ? SYS_RES_IOPORT : SYS_RES_MEMORY; - res = bus_alloc_resource(dev, space, &rid, 0, ~0, 8, RF_ACTIVE); - error = sioattach(dev); - if (error) - bus_release_resource(dev, space, rid, res); - return (error); + com->addr_rid = (id->rid >= 0) ? id->rid : -id->rid; + com->addr_type = (id->rid >= 0) ? SYS_RES_IOPORT : SYS_RES_MEMORY; + com->addr_res = bus_alloc_resource(dev, com->addr_type, &com->addr_rid, + 0, ~0, 8, RF_ACTIVE); + if (com->addr_res == NULL) + return (ENXIO); + return (sioprobe(dev)); } static int -sio_pci_probe(device_t dev) +sio_pci_attach(device_t dev) { - struct com_s *com; - struct pci_ids *id; - struct resource *res; - int error, rid, space; - com = device_get_softc(dev); - id = pci_id(dev); - if (id == NULL) - return (ENXIO); - device_set_desc(dev, id->desc); - rid = (id->rid >= 0) ? id->rid : -id->rid; - space = (id->rid >= 0) ? SYS_RES_IOPORT : SYS_RES_MEMORY; - res = bus_alloc_resource(dev, space, &rid, 0, ~0, 8, RF_ACTIVE); - com->bsh = rman_get_bushandle(res); - com->bst = rman_get_bustag(res); - -#ifdef PC98 - SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550)); -#endif - - error = sioprobe(dev); - bus_release_resource(dev, space, rid, res); - return (error); + return (sioattach(dev)); } DRIVER_MODULE(sio, pci, sio_pci_driver, sio_devclass, 0, 0); ==== //depot/projects/ia64/sys/dev/sio/sio_puc.c#7 (text+ko) ==== @@ -64,51 +64,34 @@ }; static int -sio_puc_attach(dev) - device_t dev; +sio_puc_probe(device_t dev) { struct com_s *com; - struct resource *res; - int error, rid; uintptr_t rclk; +#ifdef PC98 + SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550)); +#endif + com = device_get_softc(dev); - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 8, - RF_ACTIVE); - if (res == NULL) + com->addr_rid = 0; + com->addr_type = SYS_RES_IOPORT; + com->addr_res = bus_alloc_resource(dev, com->addr_type, &com->addr_rid, + 0, ~0, 8, RF_ACTIVE); + if (com->addr_res == NULL) return (ENXIO); - error = sioattach(dev); - if (error) - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - return (error); + + if (!BUS_READ_IVAR(device_get_parent(dev), dev, PUC_IVAR_FREQ, &rclk)) + com->rclk = rclk; + + return (sioprobe(dev)); } static int -sio_puc_probe(dev) - device_t dev; +sio_puc_attach(device_t dev) { - struct com_s *com; - struct resource *res; - int error, rid; - uintptr_t rclk; - com = device_get_softc(dev); - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 8, - RF_ACTIVE); - if (res == NULL) - return (ENXIO); - com->bsh = rman_get_bushandle(res); - com->bst = rman_get_bustag(res); - if (!BUS_READ_IVAR(device_get_parent(dev), dev, PUC_IVAR_FREQ, &rclk)) - com->rclk = rclk; -#ifdef PC98 - SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550)); -#endif - error = sioprobe(dev); - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - return (error); + return (sioattach(dev)); } DRIVER_MODULE(sio, puc, sio_puc_driver, sio_devclass, 0, 0); ==== //depot/projects/ia64/sys/dev/sio/siovar.h#13 (text+ko) ==== @@ -77,11 +77,17 @@ /* com device structure */ struct com_s { /* SIO/ng blessed. */ + device_t dev; + struct resource *irq_res; + void *irq_cookie; + struct resource *addr_res; struct consdev *consdev; /* Set for SIO console. */ int unit; bus_space_tag_t bst; bus_space_handle_t bsh; - u_long rclk; /* Receiver clock (bin 9) */ + u_long rclk; /* Receiver clock (pin 9). */ + int addr_rid; + int addr_type; /* SYS_RES_{IOPORT|MEMORY}. */ u_int regshft; /* Interleaved multi-port. */ u_int hasfifo:1; u_int fifosize; @@ -97,7 +103,6 @@ u_char extra_state; /* more flag bits, separate for order trick */ bool_t st16650a; /* Is a Startech 16650A or RTS/CTS compat */ bool_t loses_outints; /* nonzero if device loses output interrupts */ - bool_t no_irq; /* nonzero if irq is not attached */ bool_t gone; /* hardware disappeared */ bool_t poll; /* nonzero if polling is required */ bool_t poll_output; /* nonzero if polling for output is required */ @@ -146,10 +151,6 @@ u_int delta_error_counts[CE_NTYPES]; u_long error_counts[CE_NTYPES]; - struct resource *irqres; - struct resource *ioportres; - int ioportspace; - void *cookie; dev_t devs[6]; /* To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212242318.gBONIIEl022652>