Date: Sun, 22 Dec 2002 11:45:25 -0800 (PST) From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 22629 for review Message-ID: <200212221945.gBMJjPJc020286@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=22629 Change 22629 by marcel@marcel_nfs on 2002/12/22 11:44:26 Change the interface of sioprobe/sioattach: o All parameters are passed in struct com_s. This means that we don't allocate the softc anymore. In sioprobe we replace the previously allocated softc with the static one used by the serial consolei if the tag and handle of the device we're about to probe match the tag and handle of the serial console. This means that anything that we knew during console probing, we know here... o Do not deal with resources here anymore. The bus specific front-ends have the best knowledge to fiddle with the resources. Here we only work with tags and handle. o Do not test interrupts anymore. This too is better done by the bus specific front-ends. The IRQ handling is mostly in limbo. \END{CRITICAL SECTION} This obviously needs more work... Affected files ... .. //depot/projects/ia64/sys/dev/sio/sio.c#23 edit Differences ... ==== //depot/projects/ia64/sys/dev/sio/sio.c#23 (text+ko) ==== @@ -70,8 +70,6 @@ #include <sys/uio.h> #include <sys/cons.h> -#include <isa/isavar.h> - #include <machine/limits.h> #include <machine/resource.h> @@ -376,20 +374,9 @@ struct com_s *com; int i; - com = (struct com_s *) device_get_softc(dev); - if (com == NULL) { - device_printf(dev, "NULL com in siounload\n"); - return (0); - } + com = (struct com_s *)device_get_softc(dev); com->gone = 1; - for (i = 0 ; i < 6; i++) - destroy_dev(com->devs[i]); - if (com->irqres) { - bus_teardown_intr(dev, com->irqres, com->cookie); - bus_release_resource(dev, SYS_RES_IRQ, 0, com->irqres); - } - if (com->ioportres) - bus_release_resource(dev, com->ioportspace, 0, com->ioportres); + if (com->tp && (com->tp->t_state & TS_ISOPEN)) { device_printf(dev, "still open, forcing close\n"); (*linesw[com->tp->t_line].l_close)(com->tp, 0); @@ -397,27 +384,22 @@ ttyclose(com->tp); ttwakeup(com->tp); ttwwakeup(com->tp); - } else { - if (com->ibuf != NULL) - free(com->ibuf, M_DEVBUF); - device_set_softc(dev, NULL); - free(com, M_DEVBUF); } + + for (i = 0 ; i < 6; i++) + destroy_dev(com->devs[i]); + + if (com->ibuf != NULL) + free(com->ibuf, M_DEVBUF); + return (0); } int -sioprobe(dev, xrid, rclk, noprobe) - device_t dev; - int xrid; - u_long rclk; - int noprobe; +sioprobe(device_t dev) { -#if 0 - static bool_t already_init; - device_t xdev; -#endif struct com_s *com; + u_int divisor; bool_t failures[10]; int fn; @@ -425,32 +407,9 @@ u_char mcr_image; int result; u_int flags = device_get_flags(dev); - int rid, space; - struct resource *port; - rid = (xrid < 0) ? -xrid : xrid; - space = (xrid < 0) ? SYS_RES_MEMORY : SYS_RES_IOPORT; - port = bus_alloc_resource(dev, space, &rid, 0, ~0, IO_COMSIZE, - RF_ACTIVE); - if (!port) - return (ENXIO); + com = (struct com_s *)device_get_softc(dev); - if (rman_get_bustag(port) != sio_console.bst || - rman_get_bushandle(port) != sio_console.bsh) { - com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO); - if (com == NULL) - return (ENOMEM); - bzero(com, sizeof *com); - com->bst = rman_get_bustag(port); - com->bsh = rman_get_bushandle(port); - if (rclk == 0) - rclk = DEFAULT_RCLK; - com->rclk = rclk; - } else - com = &sio_console; - - device_set_softc(dev, com); - while (sio_inited != 2) if (atomic_cmpset_int(&sio_inited, 0, 1)) { mtx_init(&sio_lock, sio_driver_name, NULL, @@ -459,20 +418,21 @@ atomic_store_rel_int(&sio_inited, 2); } - if (com->consdev != NULL) { - bus_release_resource(dev, space, rid, port); + /* Check if we're probing the console. */ + if (com->bst == sio_console.bst && com->bsh == sio_console.bsh) { + com = &sio_console; + device_set_softc(dev, com); return (0); } if (COM_LLCONSOLE(flags)) { - printf("sio%d: reserved for low-level i/o\n", - device_get_unit(dev)); - bus_release_resource(dev, space, rid, port); - device_set_softc(dev, NULL); - free(com, M_DEVBUF); + device_printf(dev, "reserved for low-level i/o\n"); return (ENXIO); } + if (com->rclk == 0) + com->rclk = DEFAULT_RCLK; + /* * If the device is on a multiport card and has an AST/4 * compatible interrupt control register, initialize this @@ -487,8 +447,8 @@ 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)); + device_printf(dev, "master device %d not configured\n", + COM_MPMASTER(flags)); idev = dev; } if (!COM_NOTAST4(flags)) { @@ -506,6 +466,7 @@ } } #endif /* COM_MULTIPORT */ + if (bus_get_resource(idev, SYS_RES_IRQ, 0, NULL, NULL) != 0) mcr_image = 0; @@ -531,7 +492,7 @@ * We don't want to to wait long enough to drain at 2 bps. */ sio_setreg(com, com_lcr, LCR_DLAB | LCR_8BITS); - divisor = siodivisor(rclk, SIO_TEST_SPEED); + divisor = siodivisor(com->rclk, SIO_TEST_SPEED); sio_setreg(com, com_dlbl, divisor & 0xff); sio_setreg(com, com_dlbh, divisor >> 8); sio_setreg(com, com_lcr, LCR_8BITS); @@ -594,95 +555,30 @@ * Some pcmcia cards have the "TXRDY bug", so we check everyone * for IIR_TXRDY implementation ( Palido 321s, DC-1S... ) */ - if (noprobe) { - /* Reading IIR register twice */ - for (fn = 0; fn < 2; fn ++) { - DELAY(10000); - failures[6] = sio_getreg(com, com_iir); - } - /* Check IIR_TXRDY clear ? */ - result = 0; - if (failures[6] & IIR_TXRDY) { - /* No, Double check with clearing IER */ - sio_setreg(com, com_ier, 0); - if (sio_getreg(com, com_iir) & IIR_NOPEND) { - /* Ok. We discovered TXRDY bug! */ - SET_FLAG(dev, COM_C_IIR_TXRDYBUG); - } else { - /* Unknown, Just omit this chip.. XXX */ - result = ENXIO; - sio_setreg(com, com_mcr, 0); - } + for (fn = 0; fn < 2; fn ++) { + DELAY(10000); + failures[6] = sio_getreg(com, com_iir); + } + /* Check IIR_TXRDY clear ? */ + result = 0; + if (failures[6] & IIR_TXRDY) { + /* No, Double check with clearing IER */ + sio_setreg(com, com_ier, 0); + if (sio_getreg(com, com_iir) & IIR_NOPEND) { + /* Ok. We discovered TXRDY bug! */ + SET_FLAG(dev, COM_C_IIR_TXRDYBUG); } else { - /* OK. this is well-known guys */ - CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); + /* Unknown, Just omit this chip.. XXX */ + result = ENXIO; + sio_setreg(com, com_mcr, 0); } - sio_setreg(com, com_ier, 0); - sio_setreg(com, com_lcr, LCR_8BITS); - mtx_unlock_spin(&sio_lock); - bus_release_resource(dev, space, rid, port); - if (result != 0) { - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - } - return (result); + } else { + /* OK. this is well-known guys */ + CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); } - - /* - * Check that - * o the CFCR, IER and MCR in UART hold the values written to them - * (the values happen to be all distinct - this is good for - * avoiding false positive tests from bus echoes). - * o an output interrupt is generated and its vector is correct. - * o the interrupt goes away when the IIR in the UART is read. - */ -/* EXTRA DELAY? */ - failures[0] = sio_getreg(com, com_lcr) - LCR_8BITS; - failures[1] = sio_getreg(com, com_ier) - IER_ETXRDY; - failures[2] = sio_getreg(com, com_mcr) - mcr_image; - DELAY(10000); /* Some internal modems need this time */ - failures[4] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_TXRDY; - DELAY(1000); /* XXX */ - failures[6] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND; - - /* - * Turn off all device interrupts and check that they go off properly. - * Leave MCR_IENABLE alone. For ports without a master port, it gates - * the OUT2 output of the UART to - * the ICU input. Closing the gate would give a floating ICU input - * (unless there is another device driving it) and spurious interrupts. - * (On the system that this was first tested on, the input floats high - * and gives a (masked) interrupt as soon as the gate is closed.) - */ sio_setreg(com, com_ier, 0); - sio_setreg(com, com_lcr, LCR_8BITS); /* dummy to avoid bus echo */ - failures[7] = sio_getreg(com, com_ier); - DELAY(1000); /* XXX */ - failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND; - + sio_setreg(com, com_lcr, LCR_8BITS); mtx_unlock_spin(&sio_lock); - - result = 0; - for (fn = 0; fn < sizeof failures; ++fn) - if (failures[fn]) { - sio_setreg(com, com_mcr, 0); - result = ENXIO; - if (bootverbose) { - printf("sio%d: probe failed test(s):", - device_get_unit(dev)); - for (fn = 0; fn < sizeof failures; ++fn) - if (failures[fn]) - printf(" %d", fn); - printf("\n"); - } - break; - } - - bus_release_resource(dev, space, rid, port); - if (result != 0) { - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - } return (result); } @@ -752,10 +648,7 @@ #endif /* COM_ESP */ int -sioattach(dev, xrid, rclk) - device_t dev; - int xrid; - u_long rclk; +sioattach(device_t dev) { struct com_s *com; #ifdef COM_ESP @@ -764,20 +657,11 @@ int minorbase; int unit; u_int flags; - int rid, space; - struct resource *port; int ret; - rid = (xrid < 0) ? -xrid : xrid; - space = (xrid < 0) ? SYS_RES_MEMORY : SYS_RES_IOPORT; - port = bus_alloc_resource(dev, space, &rid, 0, ~0, IO_COMSIZE, - RF_ACTIVE); - if (!port) - return (ENXIO); - - unit = device_get_unit(dev); com = device_get_softc(dev); flags = device_get_flags(dev); + unit = device_get_unit(dev); if (unit >= sio_numunits) sio_numunits = unit + 1; @@ -798,10 +682,6 @@ * device from sending before we are ready. */ com->unit = unit; - com->ioportres = port; - com->ioportspace = space; - com->bst = rman_get_bustag(port); - com->bsh = rman_get_bushandle(port); com->cfcr_image = LCR_8BITS; com->dtr_wait = 3 * hz; com->loses_outints = COM_LOSESOUTINTS(flags) != 0; @@ -812,10 +692,6 @@ com->mcr_image = sio_getreg(com, com_mcr); - if (rclk == 0) - rclk = DEFAULT_RCLK; - com->rclk = rclk; - /* * We don't use all the flags from <sys/ttydefaults.h> since they * are only relevant for logins. It's important to have echo off @@ -837,16 +713,12 @@ com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; } else com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED; + if (siosetwater(com, com->it_in.c_ispeed) != 0) { mtx_unlock_spin(&sio_lock); - /* - * Leave i/o resources allocated if this is a `cn'-level - * console, so that other devices can't snarf them. - */ - if (com->consdev == NULL) - bus_release_resource(dev, space, rid, port); return (ENOMEM); } + mtx_unlock_spin(&sio_lock); termioschars(&com->it_in); com->it_out = com->it_in; @@ -990,9 +862,6 @@ 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, - RF_ACTIVE); if (com->irqres) { ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, INTR_TYPE_TTY | INTR_FAST, 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?200212221945.gBMJjPJc020286>
