예제 #1
0
파일: console.c 프로젝트: Alkzndr/freebsd
static int
xc_attach(device_t dev) 
{
	int error;

	xencons_dev = dev;
	xccons = tty_alloc(&xc_ttydevsw, NULL);
	tty_makedev(xccons, NULL, "xc%r", 0);

	callout_init(&xc_callout, 0);

	xencons_ring_init();

	cnsl_evt_reg = true;
	callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, xccons);
    
	if (xen_initial_domain()) {
		error = xen_intr_bind_virq(dev, VIRQ_CONSOLE, 0, NULL,
		                           xencons_priv_interrupt, NULL,
		                           INTR_TYPE_TTY, &xen_intr_handle);
		KASSERT(error >= 0, ("can't register console interrupt"));
	}

	/* register handler to flush console on shutdown */
	if ((EVENTHANDLER_REGISTER(shutdown_post_sync, xc_shutdown,
				   NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
		printf("xencons: shutdown event registration failed!\n");
	
	return (0);
}
예제 #2
0
static int
ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
{
	struct tty *tp;
	char buf[32];			/* temporary TTY device name buffer */

	tp = tty_alloc_mutex(&ucom_class, sc, sc->sc_mtx);
	if (tp == NULL)
		return (ENOMEM);

	/* Check if the client has a custom TTY name */
	buf[0] = '\0';
	if (sc->sc_callback->ucom_tty_name) {
		sc->sc_callback->ucom_tty_name(sc, buf,
		    sizeof(buf), ssc->sc_unit, sc->sc_subunit);
	}
	if (buf[0] == 0) {
		/* Use default TTY name */
		if (ssc->sc_subunits > 1) {
			/* multiple modems in one */
			snprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u.%u",
			    ssc->sc_unit, sc->sc_subunit);
		} else {
			/* single modem */
			snprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u",
			    ssc->sc_unit);
		}
	}
	tty_makedev(tp, NULL, "%s", buf);

	sc->sc_tty = tp;

	DPRINTF("ttycreate: %s\n", buf);

	/* Check if this device should be a console */
	if ((ucom_cons_softc == NULL) && 
	    (ssc->sc_unit == ucom_cons_unit) &&
	    (sc->sc_subunit == ucom_cons_subunit)) {

		DPRINTF("unit %d subunit %d is console",
		    ssc->sc_unit, sc->sc_subunit);

		ucom_cons_softc = sc;

		tty_init_console(tp, ucom_cons_baud);

		UCOM_MTX_LOCK(ucom_cons_softc);
		ucom_cons_rx_low = 0;
		ucom_cons_rx_high = 0;
		ucom_cons_tx_low = 0;
		ucom_cons_tx_high = 0;
		sc->sc_flag |= UCOM_FLAG_CONSOLE;
		ucom_open(ucom_cons_softc->sc_tty);
		ucom_param(ucom_cons_softc->sc_tty, &tp->t_termios_init_in);
		UCOM_MTX_UNLOCK(ucom_cons_softc);
	}

	return (0);
}
예제 #3
0
static void
cn_drvinit(void *unused)
{
	struct tty *tp;

	if (bvm_consdev.cn_pri != CN_DEAD &&
	    bvm_consdev.cn_name[0] != '\0') {
		tp = tty_alloc(&bvm_ttydevsw, NULL);
		tty_makedev(tp, NULL, "bvmcons");
	}
}
예제 #4
0
static void
cn_drvinit(void *unused)
{
	struct tty *tp;

	if (bvm_consdev.cn_pri != CN_DEAD) {
		tp = tty_alloc(&bvm_ttydevsw, NULL);
		callout_init_mtx(&bvm_timer, tty_getlock(tp), 0);
		tty_makedev(tp, NULL, "bvmcons");
	}
}
예제 #5
0
static
#endif /* !PTS_EXTERNAL */
int
pts_alloc(int fflags, struct thread *td, struct file *fp)
{
	int unit, ok, error;
	struct tty *tp;
	struct pts_softc *psc;
	struct proc *p = td->td_proc;
	struct ucred *cred = td->td_ucred;

	/* Resource limiting. */
	PROC_LOCK(p);
	error = racct_add(p, RACCT_NPTS, 1);
	if (error != 0) {
		PROC_UNLOCK(p);
		return (EAGAIN);
	}
	ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_NPTS));
	if (!ok) {
		racct_sub(p, RACCT_NPTS, 1);
		PROC_UNLOCK(p);
		return (EAGAIN);
	}
	PROC_UNLOCK(p);

	/* Try to allocate a new pts unit number. */
	unit = alloc_unr(pts_pool);
	if (unit < 0) {
		racct_sub(p, RACCT_NPTS, 1);
		chgptscnt(cred->cr_ruidinfo, -1, 0);
		return (EAGAIN);
	}

	/* Allocate TTY and softc. */
	psc = malloc(sizeof(struct pts_softc), M_PTS, M_WAITOK|M_ZERO);
	cv_init(&psc->pts_inwait, "ptsin");
	cv_init(&psc->pts_outwait, "ptsout");

	psc->pts_unit = unit;
	psc->pts_cred = crhold(cred);

	tp = tty_alloc(&pts_class, psc);
	knlist_init_mtx(&psc->pts_inpoll.si_note, tp->t_mtx);
	knlist_init_mtx(&psc->pts_outpoll.si_note, tp->t_mtx);

	/* Expose the slave device as well. */
	tty_makedev(tp, td->td_ucred, "pts/%u", psc->pts_unit);

	finit(fp, fflags, DTYPE_PTS, tp, &ptsdev_ops);

	return (0);
}
예제 #6
0
static int
dcons_attach_port(int port, char *name, int flags)
{
	struct dcons_softc *dc;
	struct tty *tp;

	dc = &sc[port];
	tp = tty_alloc(&dcons_ttydevsw, dc);
	dc->flags = flags;
	dc->tty   = tp;
	tty_init_console(tp, 0);
	tty_makedev(tp, NULL, "%s", name);
	return(0);
}
예제 #7
0
static int
ucom_attach_tty(struct ucom_softc *sc, uint32_t sub_units)
{
	struct tty *tp;
	int error = 0;
	char buf[32];			/* temporary TTY device name buffer */

	tp = tty_alloc_mutex(&ucom_class, sc, sc->sc_mtx);
	if (tp == NULL) {
		error = ENOMEM;
		goto done;
	}
	DPRINTF("tp = %p, unit = %d\n", tp, sc->sc_unit);

	buf[0] = 0;			/* set some default value */

	/* Check if the client has a custom TTY name */
	if (sc->sc_callback->ucom_tty_name) {
		sc->sc_callback->ucom_tty_name(sc, buf,
		    sizeof(buf), sc->sc_local_unit);
	}
	if (buf[0] == 0) {
		/* Use default TTY name */
		if (sub_units > 1) {
			/* multiple modems in one */
			if (snprintf(buf, sizeof(buf), "U%u.%u",
			    sc->sc_unit - sc->sc_local_unit,
			    sc->sc_local_unit)) {
				/* ignore */
			}
		} else {
			/* single modem */
			if (snprintf(buf, sizeof(buf), "U%u", sc->sc_unit)) {
				/* ignore */
			}
		}
	}
	tty_makedev(tp, NULL, "%s", buf);

	sc->sc_tty = tp;

	DPRINTF("ttycreate: %s\n", buf);
	cv_init(&sc->sc_cv, "ucom");

done:
	return (error);
}
예제 #8
0
int
pts_alloc_external(int fflags, struct thread *td, struct file *fp,
    struct cdev *dev, const char *name)
{
	int ok, error;
	struct tty *tp;
	struct pts_softc *psc;
	struct proc *p = td->td_proc;
	struct ucred *cred = td->td_ucred;

	/* Resource limiting. */
	PROC_LOCK(p);
	error = racct_add(p, RACCT_NPTS, 1);
	if (error != 0) {
		PROC_UNLOCK(p);
		return (EAGAIN);
	}
	ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_NPTS));
	if (!ok) {
		racct_sub(p, RACCT_NPTS, 1);
		PROC_UNLOCK(p);
		return (EAGAIN);
	}
	PROC_UNLOCK(p);

	/* Allocate TTY and softc. */
	psc = malloc(sizeof(struct pts_softc), M_PTS, M_WAITOK|M_ZERO);
	cv_init(&psc->pts_inwait, "ptsin");
	cv_init(&psc->pts_outwait, "ptsout");

	psc->pts_unit = -1;
	psc->pts_cdev = dev;
	psc->pts_cred = crhold(cred);

	tp = tty_alloc(&pts_class, psc);
	knlist_init_mtx(&psc->pts_inpoll.si_note, tp->t_mtx);
	knlist_init_mtx(&psc->pts_outpoll.si_note, tp->t_mtx);

	/* Expose the slave device as well. */
	tty_makedev(tp, td->td_ucred, "%s", name);

	finit(fp, fflags, DTYPE_PTS, tp, &ptsdev_ops);

	return (0);
}
예제 #9
0
static void
cn_drvinit(void *unused)
{

	if (mambo_consdev.cn_pri != CN_DEAD &&
	    mambo_consdev.cn_name[0] != '\0') {
		if (OF_finddevice("/mambo") == -1)
			return;

		tp = tty_alloc(&mambo_ttydevsw, NULL);
		tty_init_console(tp, 0);
		tty_makedev(tp, NULL, "%s", "mambocons");

		polltime = 1;

		callout_init(&mambo_callout, CALLOUT_MPSAFE);
		callout_reset(&mambo_callout, polltime, mambo_timeout, NULL);
	}
}
예제 #10
0
static int
uart_phyp_attach(device_t dev)
{
	struct uart_phyp_softc *sc;
	int unit;

	sc = device_get_softc(dev);
	sc->dev = dev;
	sc->node = ofw_bus_get_node(dev);
	uart_phyp_probe_node(sc);

	unit = device_get_unit(dev);
	sc->tp = tty_alloc(&uart_phyp_tty_class, sc);
	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL,
	    MTX_SPIN | MTX_QUIET | MTX_NOWITNESS);

	if (console_sc != NULL && console_sc->vtermid == sc->vtermid) {
		sc->outseqno = console_sc->outseqno;
		console_sc = sc;
		sprintf(uart_phyp_consdev.cn_name, "ttyu%r", unit);
		tty_init_console(sc->tp, 0);
	}

	sc->irqrid = 0;
	sc->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqrid,
	    RF_ACTIVE | RF_SHAREABLE);
	if (sc->irqres != NULL) {
		bus_setup_intr(dev, sc->irqres, INTR_TYPE_TTY | INTR_MPSAFE,
		    NULL, uart_phyp_intr, sc, &sc->sc_icookie);
	} else {
		callout_init(&sc->callout, CALLOUT_MPSAFE);
		sc->polltime = hz / 20;
		if (sc->polltime < 1)
			sc->polltime = 1;
		callout_reset(&sc->callout, sc->polltime, uart_phyp_intr, sc);
	}

	tty_makedev(sc->tp, NULL, "u%r", unit);

	return (0);
}
예제 #11
0
static void
cn_drvinit(void *unused)
{
	phandle_t options;
	char output[32];
	struct tty *tp;

	if (ofw_consdev.cn_pri != CN_DEAD &&
	    ofw_consdev.cn_name[0] != '\0') {
		if ((options = OF_finddevice("/options")) == -1 ||
		    OF_getprop(options, "output-device", output,
		    sizeof(output)) == -1)
			return;
		/*
		 * XXX: This is a hack and it may result in two /dev/ttya
		 * XXX: devices on platforms where the sab driver works.
		 */
		tp = tty_alloc(&ofw_ttydevsw, NULL);
		tty_makedev(tp, NULL, "%s", output);
		tty_makealias(tp, "ofwcons");
	}
}
예제 #12
0
static int
hvcn_dev_attach(device_t dev)
{
      
	struct tty *tp;
	int error, rid;

	/* belongs in attach - but attach is getting called multiple times
	 * for reasons I have not delved into
	 */

	if (hvcn_consdev.cn_pri == CN_DEAD || 
	    hvcn_consdev.cn_name[0] == '\0') 
		return (ENXIO);

	tp = tty_alloc(&hvcn_class, NULL);
	tty_makedev(tp, NULL, "v%r", 1);
	tty_makealias(tp, "hvcn");
	
	rid = 0;

	if ((hvcn_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
					RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "couldn't map interrupt\n");
		error = ENXIO;
		goto fail;
		
	}
	error = bus_setup_intr(dev, hvcn_irq, INTR_TYPE_TTY, NULL, hvcn_intr, hvcn_tp, 
			       hvcn_intrhand);
	
	if (error)
		device_printf(dev, "couldn't set up irq\n");
	
		
fail:
	return (error);
      
}
예제 #13
0
파일: uart_tty.c 프로젝트: AhmadTux/freebsd
int
uart_tty_attach(struct uart_softc *sc)
{
	struct tty *tp;
	int unit;

	sc->sc_u.u_tty.tp = tp = tty_alloc(&uart_tty_class, sc);

	unit = device_get_unit(sc->sc_dev);

	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
		sprintf(((struct consdev *)sc->sc_sysdev->cookie)->cn_name,
		    "ttyu%r", unit);
		tty_init_console(tp, 0);
	}

	swi_add(&tty_intr_event, uart_driver_name, uart_tty_intr, sc, SWI_TTY,
	    INTR_TYPE_TTY, &sc->sc_softih);

	tty_makedev(tp, NULL, "u%r", unit);

	return (0);
}
예제 #14
0
파일: si.c 프로젝트: edgar-pek/PerspicuOS
/*
 * Attach the device.  Initialize the card.
 */
int
siattach(device_t dev)
{
	int unit;
	struct si_softc *sc;
	struct si_port *pp;
	struct tty *tp;
	volatile struct si_channel *ccbp;
	volatile struct si_reg *regp;
	volatile caddr_t maddr;
	struct si_module *modp;
	int nmodule, nport, x, y;
	int uart_type;

	sc = device_get_softc(dev);
	unit = device_get_unit(dev);

	sc->sc_typename = si_type[sc->sc_type];
	if (si_numunits < unit + 1)
		si_numunits = unit + 1;

	DPRINT((0, DBG_AUTOBOOT, "si%d: siattach\n", unit));

#ifdef POLL
	if (si_pollrate == 0) {
		si_pollrate = POLLHZ;		/* in addition to irq */
#ifdef REALPOLL
		si_realpoll = 1;		/* scan always */
#endif
	}
#endif

	DPRINT((0, DBG_AUTOBOOT, "si%d: type: %s paddr: %x maddr: %x\n", unit,
		sc->sc_typename, sc->sc_paddr, sc->sc_maddr));

	sc->sc_ports = NULL;			/* mark as uninitialised */

	maddr = sc->sc_maddr;

	/* Stop the CPU first so it won't stomp around while we load */

	switch (sc->sc_type) {
#ifdef DEV_EISA
		case SIEISA:
			outb(sc->sc_iobase + 2, sc->sc_irq << 4);
#endif
		break;
		case SIPCI:
			*(maddr+SIPCIRESET) = 0;
		break;
		case SIJETPCI: /* fall through to JET ISA */
		case SIJETISA:
			*(maddr+SIJETCONFIG) = 0;
		break;
		case SIHOST2:
			*(maddr+SIPLRESET) = 0;
		break;
		case SIHOST:
			*(maddr+SIRESET) = 0;
		break;
		default: /* this should never happen */
			printf("si%d: unsupported configuration\n", unit);
			return EINVAL;
		break;
	}

	/* OK, now lets download the download code */

	if (SI_ISJET(sc->sc_type)) {
		DPRINT((0, DBG_DOWNLOAD, "si%d: jet_download: nbytes %d\n",
			unit, si3_t225_dsize));
		si_bcopy(si3_t225_download, maddr + si3_t225_downloadaddr,
			si3_t225_dsize);
		DPRINT((0, DBG_DOWNLOAD,
			"si%d: jet_bootstrap: nbytes %d -> %x\n",
			unit, si3_t225_bsize, si3_t225_bootloadaddr));
		si_bcopy(si3_t225_bootstrap, maddr + si3_t225_bootloadaddr,
			si3_t225_bsize);
	} else {
		DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n",
			unit, si2_z280_dsize));
		si_bcopy(si2_z280_download, maddr + si2_z280_downloadaddr,
			si2_z280_dsize);
	}

	/* Now start the CPU */

	switch (sc->sc_type) {
#ifdef DEV_EISA
	case SIEISA:
		/* modify the download code to tell it that it's on an EISA */
		*(maddr + 0x42) = 1;
		outb(sc->sc_iobase + 2, (sc->sc_irq << 4) | 4);
		(void)inb(sc->sc_iobase + 3); /* reset interrupt */
		break;
#endif
	case SIPCI:
		/* modify the download code to tell it that it's on a PCI */
		*(maddr+0x42) = 1;
		*(maddr+SIPCIRESET) = 1;
		*(maddr+SIPCIINTCL) = 0;
		break;
	case SIJETPCI:
		*(maddr+SIJETRESET) = 0;
		*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN;
		break;
	case SIJETISA:
		*(maddr+SIJETRESET) = 0;
		switch (sc->sc_irq) {
		case 9:
			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0x90;
			break;
		case 10:
			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xa0;
			break;
		case 11:
			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xb0;
			break;
		case 12:
			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xc0;
			break;
		case 15:
			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xf0;
			break;
		}
		break;
	case SIHOST:
		*(maddr+SIRESET_CL) = 0;
		*(maddr+SIINTCL_CL) = 0;
		break;
	case SIHOST2:
		*(maddr+SIPLRESET) = 0x10;
		switch (sc->sc_irq) {
		case 11:
			*(maddr+SIPLIRQ11) = 0x10;
			break;
		case 12:
			*(maddr+SIPLIRQ12) = 0x10;
			break;
		case 15:
			*(maddr+SIPLIRQ15) = 0x10;
			break;
		}
		*(maddr+SIPLIRQCLR) = 0x10;
		break;
	default: /* this should _REALLY_ never happen */
		printf("si%d: Uh, it was supported a second ago...\n", unit);
		return EINVAL;
	}

	DELAY(1000000);			/* wait around for a second */

	regp = (struct si_reg *)maddr;
	y = 0;
					/* wait max of 5 sec for init OK */
	while (regp->initstat == 0 && y++ < 10) {
		DELAY(500000);
	}
	switch (regp->initstat) {
	case 0:
		printf("si%d: startup timeout - aborting\n", unit);
		sc->sc_type = SIEMPTY;
		return EINVAL;
	case 1:
		if (SI_ISJET(sc->sc_type)) {
			/* set throttle to 100 times per second */
			regp->int_count = JET_INT_COUNT;
			/* rx_intr_count is a NOP in Jet */
		} else {
			/* set throttle to 125 times per second */
			regp->int_count = INT_COUNT;
			/* rx intr max of 25 times per second */
			regp->rx_int_count = RXINT_COUNT;
		}
		regp->int_pending = 0;		/* no intr pending */
		regp->int_scounter = 0;	/* reset counter */
		break;
	case 0xff:
		/*
		 * No modules found, so give up on this one.
		 */
		printf("si%d: %s - no ports found\n", unit,
			si_type[sc->sc_type]);
		return 0;
	default:
		printf("si%d: download code version error - initstat %x\n",
			unit, regp->initstat);
		return EINVAL;
	}

	/*
	 * First time around the ports just count them in order
	 * to allocate some memory.
	 */
	nport = 0;
	modp = (struct si_module *)(maddr + 0x80);
	for (;;) {
		DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp));
		switch (modp->sm_type) {
		case TA4:
			DPRINT((0, DBG_DOWNLOAD,
				"si%d: Found old TA4 module, 4 ports\n",
				unit));
			x = 4;
			break;
		case TA8:
			DPRINT((0, DBG_DOWNLOAD,
				"si%d: Found old TA8 module, 8 ports\n",
				unit));
			x = 8;
			break;
		case TA4_ASIC:
			DPRINT((0, DBG_DOWNLOAD,
				"si%d: Found ASIC TA4 module, 4 ports\n",
				unit));
			x = 4;
			break;
		case TA8_ASIC:
			DPRINT((0, DBG_DOWNLOAD,
				"si%d: Found ASIC TA8 module, 8 ports\n",
				unit));
			x = 8;
			break;
		case MTA:
			DPRINT((0, DBG_DOWNLOAD,
				"si%d: Found CD1400 module, 8 ports\n",
				unit));
			x = 8;
			break;
		case SXDC:
			DPRINT((0, DBG_DOWNLOAD,
				"si%d: Found SXDC module, 8 ports\n",
				unit));
			x = 8;
			break;
		default:
			printf("si%d: unknown module type %d\n",
				unit, modp->sm_type);
			goto try_next;
		}

		/* this was limited in firmware and is also a driver issue */
		if ((nport + x) > SI_MAXPORTPERCARD) {
			printf("si%d: extra ports ignored\n", unit);
			goto try_next;
		}

		nport += x;
		si_Nports += x;
		si_Nmodules++;

try_next:
		if (modp->sm_next == 0)
			break;
		modp = (struct si_module *)
			(maddr + (unsigned)(modp->sm_next & 0x7fff));
	}
	sc->sc_ports = (struct si_port *)malloc(sizeof(struct si_port) * nport,
		M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc->sc_ports == 0) {
		printf("si%d: fail to malloc memory for port structs\n",
			unit);
		return EINVAL;
	}
	sc->sc_nport = nport;

	/*
	 * Scan round the ports again, this time initialising.
	 */
	pp = sc->sc_ports;
	nmodule = 0;
	modp = (struct si_module *)(maddr + 0x80);
	uart_type = 1000;	/* arbitary, > uchar_max */
	for (;;) {
		switch (modp->sm_type) {
		case TA4:
			nport = 4;
			break;
		case TA8:
			nport = 8;
			break;
		case TA4_ASIC:
			nport = 4;
			break;
		case TA8_ASIC:
			nport = 8;
			break;
		case MTA:
			nport = 8;
			break;
		case SXDC:
			nport = 8;
			break;
		default:
			goto try_next2;
		}
		nmodule++;
		ccbp = (struct si_channel *)((char *)modp + 0x100);
		if (uart_type == 1000)
			uart_type = ccbp->type;
		else if (uart_type != ccbp->type)
			printf("si%d: Warning: module %d mismatch! (%d%s != %d%s)\n",
			    unit, nmodule,
			    ccbp->type, si_modulename(sc->sc_type, ccbp->type),
			    uart_type, si_modulename(sc->sc_type, uart_type));

		for (x = 0; x < nport; x++, pp++, ccbp++) {
			pp->sp_ccb = ccbp;	/* save the address */
			pp->sp_pend = IDLE_CLOSE;
			pp->sp_state = 0;	/* internal flag */
#ifdef SI_DEBUG
			sprintf(pp->sp_name, "si%r%r", unit,
			    (int)(pp - sc->sc_ports));
#endif
			tp = pp->sp_tty = tty_alloc_mutex(&si_tty_class, pp, &Giant);
			tty_makedev(tp, NULL, "A%r%r", unit, (int)(pp - sc->sc_ports));
		}
try_next2:
		if (modp->sm_next == 0) {
			printf("si%d: card: %s, ports: %d, modules: %d, type: %d%s\n",
				unit,
				sc->sc_typename,
				sc->sc_nport,
				nmodule,
				uart_type,
				si_modulename(sc->sc_type, uart_type));
			break;
		}
		modp = (struct si_module *)
			(maddr + (unsigned)(modp->sm_next & 0x7fff));
	}

	if (unit == 0)
		make_dev(&si_Scdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
		    "si_control");
	return (0);
}
예제 #15
0
int
altera_jtag_uart_attach(struct altera_jtag_uart_softc *sc)
{
	struct tty *tp;
	int error;

	AJU_LOCK_INIT(sc);

	/*
	 * XXXRW: Currently, we detect the console solely based on it using a
	 * reserved address, and borrow console-level locks and buffer if so.
	 * Is there a better way?
	 */
	if (rman_get_start(sc->ajus_mem_res) == BERI_UART_BASE) {
		sc->ajus_lockp = &aju_cons_lock;
		sc->ajus_buffer_validp = &aju_cons_buffer_valid;
		sc->ajus_buffer_datap = &aju_cons_buffer_data;
		sc->ajus_jtag_presentp = &aju_cons_jtag_present;
		sc->ajus_jtag_missedp = &aju_cons_jtag_missed;
		sc->ajus_flags |= ALTERA_JTAG_UART_FLAG_CONSOLE;
	} else {
		sc->ajus_lockp = &sc->ajus_lock;
		sc->ajus_buffer_validp = &sc->ajus_buffer_valid;
		sc->ajus_buffer_datap = &sc->ajus_buffer_data;
		sc->ajus_jtag_presentp = &sc->ajus_jtag_present;
		sc->ajus_jtag_missedp = &sc->ajus_jtag_missed;
	}

	/*
	 * Disable interrupts regardless of whether or not we plan to use
	 * them.  We will register an interrupt handler now if they will be
	 * used, but not re-enable intil later once the remainder of the tty
	 * layer is properly initialised, as we're not ready for input yet.
	 */
	AJU_LOCK(sc);
	aju_intr_disable(sc);
	AJU_UNLOCK(sc);
	if (sc->ajus_irq_res != NULL) {
		error = bus_setup_intr(sc->ajus_dev, sc->ajus_irq_res,
		    INTR_ENTROPY | INTR_TYPE_TTY | INTR_MPSAFE, NULL,
		    aju_intr, sc, &sc->ajus_irq_cookie);
		if (error) {
			device_printf(sc->ajus_dev,
			    "could not activate interrupt\n");
			AJU_LOCK_DESTROY(sc);
			return (error);
		}
	}
	tp = sc->ajus_ttyp = tty_alloc(&aju_ttydevsw, sc);
	if (sc->ajus_flags & ALTERA_JTAG_UART_FLAG_CONSOLE) {
		aju_cons_sc = sc;
		tty_init_console(tp, 0);
	}
	tty_makedev(tp, NULL, "%s%d", AJU_TTYNAME, sc->ajus_unit);

	/*
	 * If we will be using interrupts, enable them now; otherwise, start
	 * polling.  From this point onwards, input can arrive.
	 */
	if (sc->ajus_irq_res != NULL) {
		AJU_LOCK(sc);
		aju_intr_readable_enable(sc);
		AJU_UNLOCK(sc);
	} else {
		callout_init(&sc->ajus_io_callout, CALLOUT_MPSAFE);
		callout_reset(&sc->ajus_io_callout, AJU_IO_POLLINTERVAL,
		    aju_io_callout, sc);
	}
	callout_init(&sc->ajus_ac_callout, CALLOUT_MPSAFE);
	callout_reset(&sc->ajus_ac_callout, AJU_AC_POLLINTERVAL,
	    aju_ac_callout, sc);
	return (0);
}
예제 #16
0
static int
ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
{
	struct tty *tp;
	char buf[32];			/* temporary TTY device name buffer */

	tp = tty_alloc_mutex(&ucom_class, sc, sc->sc_mtx);
	if (tp == NULL)
		return (ENOMEM);

	/* Check if the client has a custom TTY name */
	buf[0] = '\0';
	if (sc->sc_callback->ucom_tty_name) {
		sc->sc_callback->ucom_tty_name(sc, buf,
		    sizeof(buf), ssc->sc_unit, sc->sc_subunit);
	}
	if (buf[0] == 0) {
		/* Use default TTY name */
		if (ssc->sc_subunits > 1) {
			/* multiple modems in one */
			snprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u.%u",
			    ssc->sc_unit, sc->sc_subunit);
		} else {
			/* single modem */
			snprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u",
			    ssc->sc_unit);
		}
	}
	tty_makedev(tp, NULL, "%s", buf);

	sc->sc_tty = tp;

	sc->sc_pps.ppscap = PPS_CAPTUREBOTH;
	sc->sc_pps.driver_abi = PPS_ABI_VERSION;
	sc->sc_pps.driver_mtx = sc->sc_mtx;
	pps_init_abi(&sc->sc_pps);

	DPRINTF("ttycreate: %s\n", buf);

	/* Check if this device should be a console */
	if ((ucom_cons_softc == NULL) && 
	    (ssc->sc_unit == ucom_cons_unit) &&
	    (sc->sc_subunit == ucom_cons_subunit)) {

		DPRINTF("unit %d subunit %d is console",
		    ssc->sc_unit, sc->sc_subunit);

		ucom_cons_softc = sc;

		tty_init_console(tp, ucom_cons_baud);

		UCOM_MTX_LOCK(ucom_cons_softc);
		ucom_cons_rx_low = 0;
		ucom_cons_rx_high = 0;
		ucom_cons_tx_low = 0;
		ucom_cons_tx_high = 0;
		sc->sc_flag |= UCOM_FLAG_CONSOLE;
		ucom_open(ucom_cons_softc->sc_tty);
		ucom_param(ucom_cons_softc->sc_tty, &tp->t_termios_init_in);
		UCOM_MTX_UNLOCK(ucom_cons_softc);
	}

	if ((ssc->sc_flag & UCOM_FLAG_DEVICE_MODE) != 0 &&
	    ucom_device_mode_console > 0 &&
	    ucom_cons_softc == NULL) {
		struct consdev *cp;

		cp = malloc(sizeof(struct consdev), M_USBDEV,
		    M_WAITOK|M_ZERO);
		cp->cn_ops = &ucom_cnops;
		cp->cn_arg = NULL;
		cp->cn_pri = CN_NORMAL;
		strlcpy(cp->cn_name, "tty", sizeof(cp->cn_name));
		strlcat(cp->cn_name, buf, sizeof(cp->cn_name));

		sc->sc_consdev = cp;

		cnadd(cp);
	}

	return (0);
}