static int xrpu_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *pr) { struct softc *sc = dev->si_drv1; int i, error; if (sc->mode == TIMECOUNTER) { i = dev2pps(dev); if (i < 0 || i >= XRPU_MAX_PPS) return ENODEV; error = pps_ioctl(cmd, arg, &sc->pps[i]); return (error); } if (cmd == XRPU_IOC_TIMECOUNTING) { struct xrpu_timecounting *xt = (struct xrpu_timecounting *)arg; /* Name SHALL be zero terminated */ xt->xt_name[sizeof xt->xt_name - 1] = '\0'; i = strlen(xt->xt_name); sc->tc.tc_name = (char *)malloc(i + 1, M_XRPU, M_WAITOK); strcpy(sc->tc.tc_name, xt->xt_name); sc->tc.tc_frequency = xt->xt_frequency; sc->tc.tc_get_timecount = xrpu_get_timecount; sc->tc.tc_poll_pps = xrpu_poll_pps; sc->tc.tc_priv = sc; sc->tc.tc_counter_mask = xt->xt_mask; sc->trigger = sc->virbase62 + xt->xt_addr_trigger; sc->latch = sc->virbase62 + xt->xt_addr_latch; for (i = 0; i < XRPU_MAX_PPS; i++) { if (xt->xt_pps[i].xt_addr_assert == 0 && xt->xt_pps[i].xt_addr_clear == 0) continue; make_dev(&xrpu_cdevsw, (i+1)<<16, UID_ROOT, GID_WHEEL, 0600, "xpps%d", i); sc->pps[i].ppscap = 0; if (xt->xt_pps[i].xt_addr_assert) { sc->assert[i] = sc->virbase62 + xt->xt_pps[i].xt_addr_assert; sc->pps[i].ppscap |= PPS_CAPTUREASSERT; } if (xt->xt_pps[i].xt_addr_clear) { sc->clear[i] = sc->virbase62 + xt->xt_pps[i].xt_addr_clear; sc->pps[i].ppscap |= PPS_CAPTURECLEAR; } pps_init(&sc->pps[i]); } sc->mode = TIMECOUNTER; init_timecounter(&sc->tc); return (0); } error = ENOTTY; return (error); }
/* * Set up the PPS cdev and the the kernel timepps stuff. * * Note that this routine cannot touch the hardware, because bus space resources * are not fully set up yet when this is called. */ static void am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc) { int unit; if (am335x_dmtimer_pps_module == -1) am335x_dmtimer_pps_find(); /* No PPS input */ if (am335x_dmtimer_pps_module == 0) return; /* Not PPS-enabled input */ if ((am335x_dmtimer_pps_module > 0) && (!ti_hwmods_contains(dev, am335x_dmtimer_pps_hwmod))) return; /* * Indicate our capabilities (pretty much just capture of either edge). * Have the kernel init its part of the pps_state struct and add its * capabilities. */ sc->pps.ppscap = PPS_CAPTUREBOTH; pps_init(&sc->pps); /* * Set up to capture the PPS via timecounter polling, and init the task * that does deferred pps_event() processing after capture. */ sc->func.tc.tc_poll_pps = am335x_dmtimer_tc_poll_pps; TASK_INIT(&sc->pps_task, 0, am335x_dmtimer_process_pps_event, sc); /* Create the PPS cdev. */ unit = device_get_unit(dev); sc->pps_cdev = make_dev(&am335x_dmtimer_pps_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, PPS_CDEV_NAME); sc->pps_cdev->si_drv1 = sc; device_printf(dev, "Using DMTimer%d for PPS device /dev/%s%d\n", am335x_dmtimer_pps_module, PPS_CDEV_NAME, unit); }
/* * Set up the PPS cdev and the the kernel timepps stuff. * * Note that this routine cannot touch the hardware, because bus space resources * are not fully set up yet when this is called. */ static int am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc) { int i, timer_num, unit; unsigned int padstate; const char * padmux; struct padinfo { char * ballname; char * muxname; int timer_num; } padinfo[] = { {"GPMC_ADVn_ALE", "timer4", 4}, {"GPMC_BEn0_CLE", "timer5", 5}, {"GPMC_WEn", "timer6", 6}, {"GPMC_OEn_REn", "timer7", 7}, }; /* * Figure out which pin the user has set up for pps. We'll use the * first timer that has an external caputure pin configured as input. * * XXX The hieroglyphic "(padstate & (0x01 << 5)))" checks that the pin * is configured for input. The right symbolic values aren't exported * yet from ti_scm.h. */ timer_num = 0; for (i = 0; i < nitems(padinfo) && timer_num == 0; ++i) { if (ti_scm_padconf_get(padinfo[i].ballname, &padmux, &padstate) == 0) { if (strcasecmp(padinfo[i].muxname, padmux) == 0 && (padstate & (0x01 << 5))) timer_num = padinfo[i].timer_num; } } if (timer_num == 0) { device_printf(dev, "No DMTimer found with capture pin " "configured as input; PPS driver disabled.\n"); return (DEFAULT_TC_TIMER); } /* * Indicate our capabilities (pretty much just capture of either edge). * Have the kernel init its part of the pps_state struct and add its * capabilities. */ sc->pps.ppscap = PPS_CAPTUREBOTH; pps_init(&sc->pps); /* * Set up to capture the PPS via timecounter polling, and init the task * that does deferred pps_event() processing after capture. */ sc->tc.tc_poll_pps = am335x_dmtimer_tc_poll_pps; TASK_INIT(&sc->pps_task, 0, am335x_dmtimer_process_pps_event, sc); /* Create the PPS cdev. */ unit = device_get_unit(dev); sc->pps_cdev = make_dev(&am335x_dmtimer_pps_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, PPS_CDEV_NAME "%d", unit); sc->pps_cdev->si_drv1 = sc; device_printf(dev, "Using DMTimer%d for PPS device /dev/%s%d\n", timer_num, PPS_CDEV_NAME, unit); return (timer_num); }
int ucomopen(dev_t dev, int flag, int mode, struct lwp *l) { int unit = UCOMUNIT(dev); usbd_status err; struct ucom_softc *sc = device_lookup_private(&ucom_cd, unit); struct ucom_buffer *ub; struct tty *tp; int s, i; int error; if (sc == NULL) return (ENXIO); if (sc->sc_dying) return (EIO); if (!device_is_active(sc->sc_dev)) return (ENXIO); tp = sc->sc_tty; DPRINTF(("ucomopen: unit=%d, tp=%p\n", unit, tp)); if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ while (sc->sc_opening) tsleep(&sc->sc_opening, PRIBIO, "ucomop", 0); if (sc->sc_dying) { splx(s); return (EIO); } sc->sc_opening = 1; if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; if (sc->sc_methods->ucom_open != NULL) { error = sc->sc_methods->ucom_open(sc->sc_parent, sc->sc_portno); if (error) { ucom_cleanup(sc); sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); return (error); } } ucom_status_change(sc); /* Clear PPS capture state on first open. */ mutex_spin_enter(&timecounter_lock); memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; pps_init(&sc->sc_pps_state); mutex_spin_exit(&timecounter_lock); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure ucomparam() will do something. */ tp->t_ospeed = 0; (void) ucomparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. Ditto RTS. */ ucom_dtr(sc, 1); ucom_rts(sc, 1); DPRINTF(("ucomopen: open pipes in=%d out=%d\n", sc->sc_bulkin_no, sc->sc_bulkout_no)); /* Open the bulk pipes */ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); if (err) { DPRINTF(("%s: open bulk in error (addr %d), err=%s\n", device_xname(sc->sc_dev), sc->sc_bulkin_no, usbd_errstr(err))); error = EIO; goto fail_0; } err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); if (err) { DPRINTF(("%s: open bulk out error (addr %d), err=%s\n", device_xname(sc->sc_dev), sc->sc_bulkout_no, usbd_errstr(err))); error = EIO; goto fail_1; } sc->sc_rx_unblock = 0; sc->sc_rx_stopped = 0; sc->sc_tx_stopped = 0; memset(sc->sc_ibuff, 0, sizeof(sc->sc_ibuff)); memset(sc->sc_obuff, 0, sizeof(sc->sc_obuff)); SIMPLEQ_INIT(&sc->sc_ibuff_empty); SIMPLEQ_INIT(&sc->sc_ibuff_full); SIMPLEQ_INIT(&sc->sc_obuff_free); SIMPLEQ_INIT(&sc->sc_obuff_full); /* Allocate input buffers */ for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; ub++) { ub->ub_xfer = usbd_alloc_xfer(sc->sc_udev); if (ub->ub_xfer == NULL) { error = ENOMEM; goto fail_2; } ub->ub_data = usbd_alloc_buffer(ub->ub_xfer, sc->sc_ibufsizepad); if (ub->ub_data == NULL) { error = ENOMEM; goto fail_2; } if (ucomsubmitread(sc, ub) != USBD_NORMAL_COMPLETION) { error = EIO; goto fail_2; } } for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS]; ub++) { ub->ub_xfer = usbd_alloc_xfer(sc->sc_udev); if (ub->ub_xfer == NULL) { error = ENOMEM; goto fail_2; } ub->ub_data = usbd_alloc_buffer(ub->ub_xfer, sc->sc_obufsize); if (ub->ub_data == NULL) { error = ENOMEM; goto fail_2; } SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link); } } sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); error = ttyopen(tp, UCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return (0); fail_2: usbd_abort_pipe(sc->sc_bulkin_pipe); for (i = 0; i < UCOM_IN_BUFFS; i++) { if (sc->sc_ibuff[i].ub_xfer != NULL) { usbd_free_xfer(sc->sc_ibuff[i].ub_xfer); sc->sc_ibuff[i].ub_xfer = NULL; sc->sc_ibuff[i].ub_data = NULL; } } usbd_abort_pipe(sc->sc_bulkout_pipe); for (i = 0; i < UCOM_OUT_BUFFS; i++) { if (sc->sc_obuff[i].ub_xfer != NULL) { usbd_free_xfer(sc->sc_obuff[i].ub_xfer); sc->sc_obuff[i].ub_xfer = NULL; sc->sc_obuff[i].ub_data = NULL; } } usbd_close_pipe(sc->sc_bulkout_pipe); sc->sc_bulkout_pipe = NULL; fail_1: usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; fail_0: sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); return (error); bad: s = spltty(); CLR(tp->t_state, TS_BUSY); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ ucom_cleanup(sc); } splx(s); return (error); }
int gtmpscopen(dev_t dev, int flag, int mode, struct lwp *l) { struct gtmpsc_softc *sc; int unit = GTMPSCUNIT(dev); struct tty *tp; int s; int error; sc = device_lookup_private(>mpsc_cd, unit); if (!sc) return ENXIO; #ifdef KGDB /* * If this is the kgdb port, no other use is permitted. */ if (sc->sc_flags & GTMPSC_KGDB) return EBUSY; #endif tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return EBUSY; s = spltty(); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; mutex_spin_enter(&sc->sc_lock); /* Turn on interrupts. */ sdma_imask |= SDMA_INTR_RXBUF(sc->sc_unit); gt_sdma_imask(device_parent(sc->sc_dev), sdma_imask); /* Clear PPS capture state on first open. */ mutex_spin_enter(&timecounter_lock); memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; pps_init(&sc->sc_pps_state); mutex_spin_exit(&timecounter_lock); mutex_spin_exit(&sc->sc_lock); if (sc->sc_flags & GTMPSC_CONSOLE) { t.c_ospeed = sc->sc_baudrate; t.c_cflag = sc->sc_cflag; } else { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; } t.c_ispeed = t.c_ospeed; /* Make sure gtmpscparam() will do something. */ tp->t_ospeed = 0; (void) gtmpscparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); mutex_spin_enter(&sc->sc_lock); /* Clear the input/output ring */ sc->sc_rcvcnt = 0; sc->sc_roffset = 0; sc->sc_rcvrx = 0; sc->sc_rcvdrx = 0; sc->sc_nexttx = 0; sc->sc_lasttx = 0; /* * enable SDMA receive */ GT_SDMA_WRITE(sc, SDMA_SDCM, SDMA_SDCM_ERD); mutex_spin_exit(&sc->sc_lock); } splx(s); error = ttyopen(tp, GTMPSCDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return 0; bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ gtmpscshutdown(sc); } return error; }