Пример #1
0
/*
 * drm_probe_helper: called by a driver at the end of its probe
 * method.
 */
int
drm_probe_helper(device_t kdev, drm_pci_id_list_t *idlist)
{
	drm_pci_id_list_t *id_entry;
	int vendor, device;

	vendor = pci_get_vendor(kdev);
	device = pci_get_device(kdev);

	if (pci_get_class(kdev) != PCIC_DISPLAY ||
	    (pci_get_subclass(kdev) != PCIS_DISPLAY_VGA &&
	     pci_get_subclass(kdev) != PCIS_DISPLAY_OTHER))
		return (-ENXIO);

	id_entry = drm_find_description(vendor, device, idlist);
	if (id_entry != NULL) {
		if (device_get_desc(kdev) == NULL) {
			DRM_DEBUG("%s desc: %s\n",
			    device_get_nameunit(kdev), id_entry->name);
			device_set_desc(kdev, id_entry->name);
		}
		return (0);
	}

	return (-ENXIO);
}
Пример #2
0
int
proto_attach(device_t dev)
{
	struct proto_softc *sc;
	struct proto_res *r;
	u_int res;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;

	for (res = 0; res < sc->sc_rescnt; res++) {
		r = sc->sc_res + res;
		switch (r->r_type) {
		case SYS_RES_IRQ:
			/* XXX TODO */
			break;
		case SYS_RES_DRQ:
			break;
		case SYS_RES_MEMORY:
		case SYS_RES_IOPORT:
			r->r_size = rman_get_size(r->r_d.res);
			r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
			    "proto/%s/%02x.%s", device_get_desc(dev), r->r_rid,
			    (r->r_type == SYS_RES_IOPORT) ? "io" : "mem");
			r->r_u.cdev->si_drv1 = sc;
			r->r_u.cdev->si_drv2 = r;
			break;
		case PROTO_RES_PCICFG:
			r->r_size = 4096;
			r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
			    "proto/%s/pcicfg", device_get_desc(dev));
			r->r_u.cdev->si_drv1 = sc;
			r->r_u.cdev->si_drv2 = r;
			break;
		case PROTO_RES_BUSDMA:
			r->r_d.busdma = proto_busdma_attach(sc);
			r->r_size = 0;	/* no read(2) nor write(2) */
			r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
			    "proto/%s/busdma", device_get_desc(dev));
			r->r_u.cdev->si_drv1 = sc;
			r->r_u.cdev->si_drv2 = r;
			break;
		}
	}
	return (0);
}
Пример #3
0
int
scc_bfe_probe(device_t dev, u_int regshft, u_int rclk, u_int rid)
{
	struct scc_softc *sc;
	struct scc_class *cl;
	u_long size, sz;
	int error;

	/*
	 * Initialize the instance. Note that the instance (=softc) does
	 * not necessarily match the hardware specific softc. We can't do
	 * anything about it now, because we may not attach to the device.
	 * Hardware drivers cannot use any of the class specific fields
	 * while probing.
	 */
	sc = device_get_softc(dev);
	cl = sc->sc_class;
	kobj_init((kobj_t)sc, (kobj_class_t)cl);
	sc->sc_dev = dev;
	if (device_get_desc(dev) == NULL)
		device_set_desc(dev, cl->name);

	size = abs(cl->cl_range) << regshft;

	/*
	 * Allocate the register resource. We assume that all SCCs have a
	 * single register window in either I/O port space or memory mapped
	 * I/O space. Any SCC that needs multiple windows will consequently
	 * not be supported by this driver as-is.
	 */
	sc->sc_rrid = rid;
	sc->sc_rtype = SYS_RES_MEMORY;
	sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
	    0, ~0, cl->cl_channels * size, RF_ACTIVE);
	if (sc->sc_rres == NULL) {
		sc->sc_rrid = rid;
		sc->sc_rtype = SYS_RES_IOPORT;
		sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype,
		    &sc->sc_rrid, 0, ~0, cl->cl_channels * size, RF_ACTIVE);
		if (sc->sc_rres == NULL)
			return (ENXIO);
	}

	/*
	 * Fill in the bus access structure and call the hardware specific
	 * probe method.
	 */
	sz = (size != 0) ? size : rman_get_size(sc->sc_rres);
	sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
	sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
	sc->sc_bas.range = sz;
	sc->sc_bas.rclk = rclk;
	sc->sc_bas.regshft = regshft;

	error = SCC_PROBE(sc);
	bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
	return ((error == 0) ? BUS_PROBE_DEFAULT : error);
}
Пример #4
0
int
proto_probe(device_t dev, const char *prefix, char ***devnamesp)
{
	char **devnames = *devnamesp;
	const char *dn, *ep, *ev;
	size_t pfxlen;
	int idx, names;

	if (devnames == NULL) {
		pfxlen = strlen(prefix);
		names = 1;	/* NULL pointer */
		ev = kern_getenv("hw.proto.attach");
		if (ev != NULL) {
			dn = ev;
			while (*dn != '\0') {
				ep = dn;
				while (*ep != ',' && *ep != '\0')
					ep++;
				if ((ep - dn) > pfxlen &&
				    strncmp(dn, prefix, pfxlen) == 0)
					names++;
				dn = (*ep == ',') ? ep + 1 : ep;
			}
		}
		devnames = malloc(names * sizeof(caddr_t), M_DEVBUF,
		    M_WAITOK | M_ZERO);
		*devnamesp = devnames;
		if (ev != NULL) {
			dn = ev;
			idx = 0;
			while (*dn != '\0') {
				ep = dn;
				while (*ep != ',' && *ep != '\0')
					ep++;
				if ((ep - dn) > pfxlen &&
				    strncmp(dn, prefix, pfxlen) == 0) {
					devnames[idx] = malloc(ep - dn + 1,
					    M_DEVBUF, M_WAITOK | M_ZERO);
					memcpy(devnames[idx], dn, ep - dn);
					idx++;
				}
				dn = (*ep == ',') ? ep + 1 : ep;
			}
			freeenv(__DECONST(char *, ev));
		}
	}

	dn = device_get_desc(dev);
	while (*devnames != NULL) {
		if (strcmp(dn, *devnames) == 0)
			return (BUS_PROBE_SPECIFIC);
		devnames++;
	}
	return (BUS_PROBE_HOOVER);
}
Пример #5
0
static int
ucom_detach(device_t self)
{       
        struct ucom_softc *sc = device_get_softc(self);
	char *devinfo = (char *) device_get_desc(self);

	if (devinfo) {
		device_set_desc(self, NULL);
		free(devinfo, M_USB);
	}
	return 0;
}
/*------------------------------------------------------------------------*
 *	ugen_get_iface_driver
 *
 * This function generates an USB interface description for userland.
 *
 * Returns:
 *    0: Success
 * Else: Failure
 *------------------------------------------------------------------------*/
static int
ugen_get_iface_driver(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
{
	struct usb_device *udev = f->udev;
	struct usb_interface *iface;
	const char *ptr;
	const char *desc;
	unsigned int len;
	unsigned int maxlen;
	char buf[128];
	int error;

	DPRINTFN(6, "\n");

	if ((ugd->ugd_data == NULL) || (ugd->ugd_maxlen == 0)) {
		/* userland pointer should not be zero */
		return (EINVAL);
	}

	iface = usbd_get_iface(udev, ugd->ugd_iface_index);
	if ((iface == NULL) || (iface->idesc == NULL)) {
		/* invalid interface index */
		return (EINVAL);
	}

	/* read out device nameunit string, if any */
	if ((iface->subdev != NULL) &&
	    device_is_attached(iface->subdev) &&
	    (ptr = device_get_nameunit(iface->subdev)) &&
	    (desc = device_get_desc(iface->subdev))) {

		/* print description */
		snprintf(buf, sizeof(buf), "%s: <%s>", ptr, desc);

		/* range checks */
		maxlen = ugd->ugd_maxlen - 1;
		len = strlen(buf);
		if (len > maxlen)
			len = maxlen;

		/* update actual length, including terminating zero */
		ugd->ugd_actlen = len + 1;

		/* copy out interface description */
		error = copyout(buf, ugd->ugd_data, ugd->ugd_actlen);
	} else {
		/* zero length string is default */
		error = copyout("", ugd->ugd_data, 1);
	}
	return (error);
}
Пример #7
0
static int
km_probe(struct device *dev)
{
	char *desc;

	if (pci_get_vendor(dev) != PCI_VENDOR_AMD)
		return ENXIO;

	switch (pci_get_device(dev)) {
	case PCI_PRODUCT_AMD_AMD64_F10_MISC:
		desc = "AMD Family 10h temperature sensor";
		break;
	case PCI_PRODUCT_AMD_AMD64_F11_MISC:
		desc = "AMD Family 11h temperature sensor";
		break;
	case PCI_PRODUCT_AMD_AMD64_F14_MISC:
		if (CPUID_TO_FAMILY(cpu_id) == 0x12)
			desc = "AMD Family 12h temperature sensor";
		else
			desc = "AMD Family 14h temperature sensor";
		break;
	case PCI_PRODUCT_AMD_AMD64_F15_0x_MISC:
		desc = "AMD Family 15/0xh temperature sensor";
		break;
	case PCI_PRODUCT_AMD_AMD64_F15_1x_MISC:
		desc = "AMD Family 15/1xh temperature sensor";
		break;
	case PCI_PRODUCT_AMD_AMD64_F15_3x_MISC:
		desc = "AMD Family 15/3xh temperature sensor";
		break;
	case PCI_PRODUCT_AMD_AMD64_F16_MISC:
		desc = "AMD Family 16h temperature sensor";
		break;
	default:
		return ENXIO;
	}

	if (device_get_desc(dev) == NULL)
		device_set_desc(dev, desc);
	return 0;
}
Пример #8
0
static int
km_probe(struct device *dev)
{
	int ten = 0;

	if (pci_get_vendor(dev) != PCI_VENDOR_AMD)
		return ENXIO;

	switch (pci_get_device(dev)) {
	case PCI_PRODUCT_AMD_AMD64_F10_MISC:
		ten = 1;
		/* FALLTHROUGH */
	case PCI_PRODUCT_AMD_AMD64_F11_MISC:
		if (device_get_desc(dev) == NULL)
			device_set_desc(dev, ten ?
			    "AMD Family 10h temperature sensor" :
			    "AMD Family 11h temperature sensor");
		return 0;
	default:
		return ENXIO;
	}
}
Пример #9
0
int
quicc_bfe_probe(device_t dev, u_int clock)
{
	struct quicc_softc *sc;
	uint16_t rev;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	if (device_get_desc(dev) == NULL)
		device_set_desc(dev,
		    "Quad integrated communications controller");

	sc->sc_rrid = 0;
	sc->sc_rtype = SYS_RES_MEMORY;
	sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
	    0, ~0, 0, RF_ACTIVE);
	if (sc->sc_rres == NULL) {
		sc->sc_rrid = 0;
		sc->sc_rtype = SYS_RES_IOPORT;
		sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype,
		    &sc->sc_rrid, 0, ~0, 0, RF_ACTIVE);
		if (sc->sc_rres == NULL)
			return (ENXIO);
	}

	sc->sc_clock = clock;

	/*
	 * Check that the microcode revision is 0x00e8, as documented
	 * in the MPC8555E PowerQUICC III Integrated Processor Family
	 * Reference Manual.
	 */
	rev = quicc_read2(sc->sc_rres, QUICC_PRAM_REV_NUM);

	bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
	return ((rev == 0x00e8) ? BUS_PROBE_DEFAULT : ENXIO);
}
Пример #10
0
static int
gmbus_xfer(device_t adapter,
	   struct iic_msg *msgs,
	   uint32_t num)
{
	struct intel_iic_softc *sc = device_get_softc(adapter);
	struct intel_gmbus *bus = sc->bus;
	struct drm_i915_private *dev_priv = bus->dev_priv;
	int i, reg_offset;
	int ret = 0;

	sx_xlock(&dev_priv->gmbus_mutex);

	if (bus->force_bit) {
		ret = -IICBUS_TRANSFER(bus->bbbus, msgs, num);
		goto out;
	}

	reg_offset = dev_priv->gpio_mmio_base;

	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);

	for (i = 0; i < num; i++) {
		u32 gmbus2;

		if (gmbus_is_index_read(msgs, i, num)) {
			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
			i += 1;  /* set i to the index of the read xfer */
		} else if (msgs[i].flags & I2C_M_RD) {
			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
		} else {
			ret = gmbus_xfer_write(dev_priv, &msgs[i]);
		}

		if (ret == -ETIMEDOUT)
			goto timeout;
		if (ret == -ENXIO)
			goto clear_err;

		ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) &
			       (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE),
			       50);
		if (ret)
			goto timeout;
		if (gmbus2 & GMBUS_SATOER)
			goto clear_err;
	}

	/* Generate a STOP condition on the bus. Note that gmbus can't generata
	 * a STOP on the very first cycle. To simplify the code we
	 * unconditionally generate the STOP condition with an additional gmbus
	 * cycle. */
	I915_WRITE(GMBUS1 + reg_offset, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);

	/* Mark the GMBUS interface as disabled after waiting for idle.
	 * We will re-enable it at the start of the next xfer,
	 * till then let it sleep.
	 */
	if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0,
		     10)) {
		DRM_DEBUG_KMS("GMBUS [%s] timed out waiting for idle\n",
			 device_get_desc(adapter));
		ret = -ETIMEDOUT;
	}
	I915_WRITE(GMBUS0 + reg_offset, 0);
	goto out;

clear_err:
	/*
	 * Wait for bus to IDLE before clearing NAK.
	 * If we clear the NAK while bus is still active, then it will stay
	 * active and the next transaction may fail.
	 *
	 * If no ACK is received during the address phase of a transaction, the
	 * adapter must report -ENXIO. It is not clear what to return if no ACK
	 * is received at other times. But we have to be careful to not return
	 * spurious -ENXIO because that will prevent i2c and drm edid functions
	 * from retrying. So return -ENXIO only when gmbus properly quiescents -
	 * timing out seems to happen when there _is_ a ddc chip present, but
	 * it's slow responding and only answers on the 2nd retry.
	 */
	ret = -ENXIO;
	if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0,
		     10)) {
		DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n",
			      device_get_desc(adapter));
		ret = -ETIMEDOUT;
	}

	/* Toggle the Software Clear Interrupt bit. This has the effect
	 * of resetting the GMBUS controller and so clearing the
	 * BUS_ERROR raised by the slave's NAK.
	 */
	I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT);
	I915_WRITE(GMBUS1 + reg_offset, 0);
	I915_WRITE(GMBUS0 + reg_offset, 0);

	DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n",
			 device_get_desc(adapter), msgs[i].slave >> 1,
			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);

	goto out;

timeout:
	DRM_INFO("GMBUS [%s] timed out, falling back to bit banging on pin %d\n",
		 device_get_desc(adapter), bus->reg0 & 0xff);
	I915_WRITE(GMBUS0 + reg_offset, 0);

	/* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
	bus->force_bit = 1;
	ret = -IICBUS_TRANSFER(bus->bbbus, msgs, num);

out:
	sx_xunlock(&dev_priv->gmbus_mutex);
	return -ret;
}
Пример #11
0
/*---------------------------------------------------------------------------*
 *      attach for ISA PnP cards
 *---------------------------------------------------------------------------*/
static int
isic_pnp_attach(device_t dev)
{
	u_int32_t vend_id = isa_get_vendorid(dev);	/* vendor id */
	unsigned int unit = device_get_unit(dev);	/* get unit */
	const char *name = device_get_desc(dev);	/* get description */
	struct l1_softc *sc = 0;			/* softc */
	void *ih = 0;					/* a dummy */
	int ret;
 
	/* see if we are out of bounds */
	
	if(unit >= ISIC_MAXUNIT)
	{
		printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for %s\n", unit, unit, name);
		return ENXIO;
	}

	/* get information structure for this unit */

	sc = &l1_sc[unit];

	/* get io_base */
	if(!(sc->sc_resources.io_base[0] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
						&sc->sc_resources.io_rid[0],
						0UL, ~0UL, 1, RF_ACTIVE ) ))
	{
		printf("isic_pnp_attach: Couldn't get my io_base.\n");
		return ENXIO;                                       
	}
	
	/* will not be used for pnp devices */

	sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);

	/* get irq, release io_base if we don't get it */

	if(!(sc->sc_resources.irq =
			bus_alloc_resource(dev, SYS_RES_IRQ,
					   &sc->sc_resources.irq_rid,
					   0UL, ~0UL, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not get irq.\n",unit);
		isic_detach_common(dev);
		return ENXIO;                                       
	}
	
	/* not needed */
	sc->sc_irq = rman_get_start(sc->sc_resources.irq);


	/* set flag so we know what this card is */

	ret = ENXIO;
	
	switch(vend_id)
	{
#if defined(TEL_S0_16_3_P) || defined(CRTX_S0_P) || defined(COMPAQ_M610)
		case VID_TEL163PNP:
			sc->sc_cardtyp = CARD_TYPEP_163P;
			ret = isic_attach_Cs0P(dev);
			break;

		case VID_CREATIXPP:
			sc->sc_cardtyp = CARD_TYPEP_CS0P;
			ret = isic_attach_Cs0P(dev);
			break;

		case VID_COMPAQ_M610:
			sc->sc_cardtyp = CARD_TYPEP_COMPAQ_M610;
			ret = isic_attach_Cs0P(dev);
			break;
#endif
#ifdef DYNALINK
		case VID_DYNALINK:
			sc->sc_cardtyp = CARD_TYPEP_DYNALINK;
			ret = isic_attach_Dyn(dev);
			break;
#endif
#ifdef SEDLBAUER
		case VID_SEDLBAUER:
			sc->sc_cardtyp = CARD_TYPEP_SWS;
			ret = isic_attach_sws(dev);
			break;
#endif
#ifdef DRN_NGO
		case VID_NICCYGO:
			sc->sc_cardtyp = CARD_TYPEP_DRNNGO;
			ret = isic_attach_drnngo(dev);
			break;
#endif
#ifdef ELSA_QS1ISA
		case VID_ELSAQS1P:
			sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA;
			ret = isic_attach_Eqs1pi(dev);
			break;
#endif
#ifdef ITKIX1
		case VID_ITK0025:
			sc->sc_cardtyp = CARD_TYPEP_ITKIX1;
			ret = isic_attach_itkix1(dev);
			break;
#endif			
#ifdef SIEMENS_ISURF2
		case VID_SIESURF2:
			sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2;
			ret = isic_attach_siemens_isurf(dev);
			break;
#endif
#ifdef ASUSCOM_IPAC
		case VID_ASUSCOM_IPAC:
			sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC;
			ret = isic_attach_asi(dev);
			break;
#endif
#ifdef EICON_DIVA
		case VID_EICON_DIVA_20:
			sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
			ret = isic_attach_diva(dev);
			break;
		
		case VID_EICON_DIVA_202:
			sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
			ret = isic_attach_diva_ipac(dev);
			break;
#endif
		default:
			printf("isic%d: Error, no driver for %s\n", unit, name);
			ret = ENXIO;
			break;		
	}

	if(ret)
	{
		isic_detach_common(dev);
		return ENXIO;                                       
	}		
		
	if(isic_attach_common(dev))
	{
		/* unset flag */
		sc->sc_cardtyp = CARD_TYPEP_UNK;

		/* free irq here, it hasn't been attached yet */
		bus_release_resource(dev,SYS_RES_IRQ,sc->sc_resources.irq_rid,
					sc->sc_resources.irq);
		sc->sc_resources.irq = 0;
		isic_detach_common(dev);
		return ENXIO;
	}
	else
	{
		/* setup intr routine */
		bus_setup_intr(dev,sc->sc_resources.irq,INTR_TYPE_NET,
				(void(*)(void*))isicintr,
				sc,&ih);
		return 0;
	}
}
Пример #12
0
Файл: zs.c Проект: MarginC/kame
int
zstty_attach(device_t dev)
{
	struct zstty_softc *sc;
	struct tty *tp;
	char mode[32];
	int reset;
	int baud;
	int clen;
	char parity;
	int stop;
	char c;

	sc = device_get_softc(dev);
	mtx_init(&sc->sc_mtx, "zstty", NULL, MTX_SPIN);
	sc->sc_dev = dev;
	sc->sc_iput = sc->sc_iget = sc->sc_ibuf;
	sc->sc_oget = sc->sc_obuf;

	tp = ttymalloc(NULL);
	sc->sc_si = make_dev(&zstty_cdevsw, device_get_unit(dev),
	    UID_ROOT, GID_WHEEL, 0600, "%s", device_get_desc(dev));
	sc->sc_si->si_drv1 = sc;
	sc->sc_si->si_tty = tp;
	tp->t_dev = sc->sc_si;
	sc->sc_tty = tp;

	tp->t_oproc = zsttystart;
	tp->t_param = zsttyparam;
	tp->t_stop = zsttystop;
	tp->t_iflag = TTYDEF_IFLAG;
	tp->t_oflag = TTYDEF_OFLAG;
	tp->t_lflag = TTYDEF_LFLAG;
	tp->t_cflag = CREAD | CLOCAL | CS8;
	tp->t_ospeed = TTYDEF_SPEED;
	tp->t_ispeed = TTYDEF_SPEED;

	if (zstty_console(dev, mode, sizeof(mode))) {
		ttychars(tp);
		/* format: 9600,8,n,1,- */
		if (sscanf(mode, "%d,%d,%c,%d,%c", &baud, &clen, &parity,
		    &stop, &c) == 5) {
			tp->t_ospeed = baud;
			tp->t_ispeed = baud;
			tp->t_cflag = CREAD | CLOCAL;
			switch (clen) {
			case 5:
				tp->t_cflag |= CS5;
				break;
			case 6:
				tp->t_cflag |= CS6;
				break;
			case 7:
				tp->t_cflag |= CS7;
				break;
			case 8:
			default:
				tp->t_cflag |= CS8;
				break;
			}

			if (parity == 'e')
				tp->t_cflag |= PARENB;
			else if (parity == 'o')
				tp->t_cflag |= PARENB | PARODD;

			if (stop == 2)
				tp->t_cflag |= CSTOPB;
		}
		device_printf(dev, "console %s\n", mode);
		sc->sc_console = 1;
		zstty_cons = sc;
	} else {
		if ((device_get_unit(dev) & 1) == 0)
			reset = ZSWR9_A_RESET;
		else
			reset = ZSWR9_B_RESET;
		ZS_WRITE_REG(sc, 9, reset);
	}

	return (0);
}
Пример #13
0
/*
 * Quiz the PnP BIOS, build a list of PNP IDs and resource data.
 */
static int
pnpbios_identify(driver_t *driver, device_t parent)
{
    struct PnPBIOS_table	*pt = PnPBIOStable;
    struct bios_args		args;
    struct pnp_sysdev		*pd;
    struct pnp_sysdevargs	*pda;
    uint16_t			ndevs, bigdev;
    int				error, currdev;
    uint8_t			*devnodebuf, tag;
    uint32_t			*devid, *compid;
    int				idx, left;
    device_t			dev;

    /*
     * Umm, we aren't going to rescan the PnP BIOS to look for new additions.
     */
    if (device_get_state(parent) == DS_ATTACHED)
	return (0);
        
    /* no PnP BIOS information */
    if (pt == NULL)
	return (ENXIO);

    /* ACPI already active */
    if (devclass_get_softc(devclass_find("ACPI"), 0) != NULL)
	return (ENXIO);
    
    bzero(&args, sizeof(args));
    args.seg.code16.base = BIOS_PADDRTOVADDR(pt->pmentrybase);
    args.seg.code16.limit = 0xffff;		/* XXX ? */
    args.seg.data.base = BIOS_PADDRTOVADDR(pt->pmdataseg);
    args.seg.data.limit = 0xffff;
    args.entry = pt->pmentryoffset;

    if ((error = bios16(&args, PNP_COUNT_DEVNODES, &ndevs, &bigdev)) || (args.r.eax & 0xff))
	kprintf("pnpbios: error %d/%x getting device count/size limit\n", error, args.r.eax);
    ndevs &= 0xff;				/* clear high byte garbage */
    if (bootverbose)
	kprintf("pnpbios: %d devices, largest %d bytes\n", ndevs, bigdev);

    devnodebuf = kmalloc(bigdev + (sizeof(struct pnp_sysdevargs) - sizeof(struct pnp_sysdev)), M_DEVBUF, M_INTWAIT);
    pda = (struct pnp_sysdevargs *)devnodebuf;
    pd = &pda->node;

    for (currdev = 0, left = ndevs; (currdev != 0xff) && (left > 0); left--) {
	bzero(pd, bigdev);
	pda->next = currdev;

	/* get current configuration */
	if ((error = bios16(&args, PNP_GET_DEVNODE, &pda->next, &pda->node, 1))) {
	    kprintf("pnpbios: error %d making BIOS16 call\n", error);
	    break;
	}
	if (bootverbose)
	    kprintf("pnp_get_devnode cd=%d nxt=%d size=%d handle=%d devid=%08x type=%02x%02x%02x, attrib=%04x\n", currdev, pda->next, pd->size, pd->handle, pd->devid, pd->type[0], pd->type[1], pd->type[2], pd->attrib);

	if ((error = (args.r.eax & 0xff))) {
	    if (bootverbose)
		kprintf("pnpbios: %s 0x%x fetching node %d\n", error & 0x80 ? "error" : "warning", error, currdev);
	    if (error & 0x80) 
		break;
	}
	currdev = pda->next;
	if (pd->size < sizeof(struct pnp_sysdev)) {
	    kprintf("pnpbios: bogus system node data, aborting scan\n");
	    break;
	}
	
	/*
	 * Ignore PICs so that we don't have to worry about the PICs
	 * claiming IRQs to prevent their use.  The PIC drivers
	 * already ensure that invalid IRQs are not used.
	 */
	if (!strcmp(pnp_eisaformat(pd->devid), "PNP0000"))	/* ISA PIC */
	    continue;
	if (!strcmp(pnp_eisaformat(pd->devid), "PNP0003"))	/* APIC */
	    continue;

	/* Add the device and parse its resources */
	dev = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP, NULL, -1);
	isa_set_vendorid(dev, pd->devid);
	isa_set_logicalid(dev, pd->devid);

	/*
	 * It appears that some PnP BIOS doesn't allow us to re-enable
	 * the embedded system device once it is disabled.  We shall
	 * mark all system device nodes as "cannot be disabled", regardless
	 * of actual settings in the device attribute byte.  XXX
	 */
#if 0
	isa_set_configattr(dev, 
	    ((pd->attrib & PNPATTR_NODISABLE) ?  0 : ISACFGATTR_CANDISABLE) |
	    ((!(pd->attrib & PNPATTR_NOCONFIG) && 
		PNPATTR_CONFIG(pd->attrib) != PNPATTR_CONFIG_STATIC)
		? ISACFGATTR_DYNAMIC : 0));
#endif
	isa_set_configattr(dev, 
	    (!(pd->attrib & PNPATTR_NOCONFIG) && 
		PNPATTR_CONFIG(pd->attrib) != PNPATTR_CONFIG_STATIC)
		? ISACFGATTR_DYNAMIC : 0);

	ISA_SET_CONFIG_CALLBACK(parent, dev, pnpbios_set_config, 0);
	pnp_parse_resources(dev, &pd->devdata[0],
			    pd->size - sizeof(struct pnp_sysdev), 0);
	if (!device_get_desc(dev))
	    device_set_desc_copy(dev, pnp_eisaformat(pd->devid));

	/* Find device IDs */
	devid = &pd->devid;
	compid = NULL;

	/* look for a compatible device ID too */
	left = pd->size - sizeof(struct pnp_sysdev);
	idx = 0;
	while (idx < left) {
	    tag = pd->devdata[idx++];
	    if (PNP_RES_TYPE(tag) == 0) {
		/* Small resource */
		switch (PNP_SRES_NUM(tag)) {
		case PNP_TAG_COMPAT_DEVICE:
		    compid = (uint32_t *)(pd->devdata + idx);
		    if (bootverbose)
			kprintf("pnpbios: node %d compat ID 0x%08x\n", pd->handle, *compid);
		    /* FALLTHROUGH */
		case PNP_TAG_END:
		    idx = left;
		    break;
		default:
		    idx += PNP_SRES_LEN(tag);
		    break;
		}
	    } else
		/* Large resource, skip it */
		idx += *(uint16_t *)(pd->devdata + idx) + 2;
	}
	if (bootverbose) {
	    kprintf("pnpbios: handle %d device ID %s (%08x)", 
		   pd->handle, pnp_eisaformat(*devid), *devid);
	    if (compid != NULL)
		kprintf(" compat ID %s (%08x)",
		       pnp_eisaformat(*compid), *compid);
	    kprintf("\n");
	}
    }
    return (0);
}
Пример #14
0
static int
aw_ir_attach(device_t dev)
{
	struct aw_ir_softc *sc;
	hwreset_t rst_apb;
	clk_t clk_ir, clk_gate;
	int err;
	uint32_t val = 0;

	clk_ir = clk_gate = NULL;
	rst_apb = NULL;

	sc = device_get_softc(dev);
	sc->dev = dev;

	if (bus_alloc_resources(dev, aw_ir_spec, sc->res) != 0) {
		device_printf(dev, "could not allocate memory resource\n");
		return (ENXIO);
	}

	switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
	case A10_IR:
		sc->fifo_size = 16;
		break;
	case A13_IR:
		sc->fifo_size = 64;
		break;
	}

	/* De-assert reset */
	if (hwreset_get_by_ofw_name(dev, 0, "apb", &rst_apb) == 0) {
		err = hwreset_deassert(rst_apb);
		if (err != 0) {
			device_printf(dev, "cannot de-assert reset\n");
			goto error;
		}
	}

	/* Reset buffer */
	aw_ir_buf_reset(sc);

	/* Get clocks and enable them */
	err = clk_get_by_ofw_name(dev, 0, "apb", &clk_gate);
	if (err != 0) {
		device_printf(dev, "Cannot get gate clock\n");
		goto error;
	}
	err = clk_get_by_ofw_name(dev, 0, "ir", &clk_ir);
	if (err != 0) {
		device_printf(dev, "Cannot get IR clock\n");
		goto error;
	}
	/* Set clock rate */
	err = clk_set_freq(clk_ir, AW_IR_BASE_CLK, 0);
	if (err != 0) {
		device_printf(dev, "cannot set IR clock rate\n");
		goto error;
	}
	/* Enable clocks */
	err = clk_enable(clk_gate);
	if (err != 0) {
		device_printf(dev, "Cannot enable clk gate\n");
		goto error;
	}
	err = clk_enable(clk_ir);
	if (err != 0) {
		device_printf(dev, "Cannot enable IR clock\n");
		goto error;
	}

	if (bus_setup_intr(dev, sc->res[1],
	    INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_ir_intr, sc,
	    &sc->intrhand)) {
		bus_release_resources(dev, aw_ir_spec, sc->res);
		device_printf(dev, "cannot setup interrupt handler\n");
		return (ENXIO);
	}

	/* Enable CIR Mode */
	WRITE(sc, AW_IR_CTL, AW_IR_CTL_MD);

	/*
	 * Set clock sample, filter, idle thresholds.
	 * Frequency sample = 3MHz/128 = 23437.5Hz (42.7us)
	 */
	val = AW_IR_SAMPLE_128;
	val |= (AW_IR_RXFILT_VAL | AW_IR_RXIDLE_VAL);
	val |= (AW_IR_ACTIVE_T | AW_IR_ACTIVE_T_C);
	WRITE(sc, AW_IR_CIR, val);

	/* Invert Input Signal */
	WRITE(sc, AW_IR_RXCTL, AW_IR_RXCTL_RPPI);

	/* Clear All RX Interrupt Status */
	WRITE(sc, AW_IR_RXSTA, AW_IR_RXSTA_CLEARALL);

	/*
	 * Enable RX interrupt in case of overflow, packet end
	 * and FIFO available.
	 * RX FIFO Threshold = FIFO size / 2
	 */
	WRITE(sc, AW_IR_RXINT, AW_IR_RXINT_ROI_EN | AW_IR_RXINT_RPEI_EN |
	    AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RAL((sc->fifo_size >> 1) - 1));

	/* Enable IR Module */
	val = READ(sc, AW_IR_CTL);
	WRITE(sc, AW_IR_CTL, val | AW_IR_CTL_GEN | AW_IR_CTL_RXEN);

	sc->sc_evdev = evdev_alloc();
	evdev_set_name(sc->sc_evdev, device_get_desc(sc->dev));
	evdev_set_phys(sc->sc_evdev, device_get_nameunit(sc->dev));
	evdev_set_id(sc->sc_evdev, BUS_HOST, 0, 0, 0);
	evdev_support_event(sc->sc_evdev, EV_SYN);
	evdev_support_event(sc->sc_evdev, EV_MSC);
	evdev_support_msc(sc->sc_evdev, MSC_SCAN);

	err = evdev_register(sc->sc_evdev);
	if (err) {
		device_printf(dev,
		    "failed to register evdev: error=%d\n", err);
		goto error;
	}

	return (0);
error:
	if (clk_gate != NULL)
		clk_release(clk_gate);
	if (clk_ir != NULL)
		clk_release(clk_ir);
	if (rst_apb != NULL)
		hwreset_release(rst_apb);
	evdev_free(sc->sc_evdev);
	sc->sc_evdev = NULL;	/* Avoid double free */

	bus_release_resources(dev, aw_ir_spec, sc->res);
	return (ENXIO);
}
Пример #15
0
static int
ichwd_attach(device_t dev)
{
    struct ichwd_softc *sc;
    struct ichwd_device *id_p;
    device_t ich;
    unsigned int pmbase = 0;

    sc = device_get_softc(dev);
    sc->device = dev;

    ich = ichwd_find_ich_lpc_bridge(&id_p);
    if (ich == NULL) {
        device_printf(sc->device, "Can not find ICH device.\n");
        goto fail;
    }
    sc->ich = ich;
    sc->ich_version = id_p->version;

    /* get ACPI base address */
    pmbase = pci_read_config(ich, ICH_PMBASE, 2) & ICH_PMBASE_MASK;
    if (pmbase == 0) {
        device_printf(dev, "ICH PMBASE register is empty\n");
        goto fail;
    }

    /* allocate I/O register space */
    sc->smi_rid = 0;
    sc->smi_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->smi_rid,
                                     pmbase + SMI_BASE, pmbase + SMI_BASE + SMI_LEN - 1, SMI_LEN,
                                     RF_ACTIVE | RF_SHAREABLE);
    if (sc->smi_res == NULL) {
        device_printf(dev, "unable to reserve SMI registers\n");
        goto fail;
    }

    sc->tco_rid = 1;
    sc->tco_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->tco_rid,
                                     pmbase + TCO_BASE, pmbase + TCO_BASE + TCO_LEN - 1, TCO_LEN,
                                     RF_ACTIVE | RF_SHAREABLE);
    if (sc->tco_res == NULL) {
        device_printf(dev, "unable to reserve TCO registers\n");
        goto fail;
    }

    sc->gcs_rid = 0;
    if (sc->ich_version >= 6) {
        sc->gcs_res = bus_alloc_resource_any(ich, SYS_RES_MEMORY,
                                             &sc->gcs_rid, RF_ACTIVE|RF_SHAREABLE);
        if (sc->gcs_res == NULL) {
            device_printf(dev, "unable to reserve GCS registers\n");
            goto fail;
        }
    }

    if (ichwd_clear_noreboot(sc) != 0)
        goto fail;

    ichwd_verbose_printf(dev, "%s (ICH%d or equivalent)\n",
                         device_get_desc(dev), sc->ich_version);

    /*
     * Determine if we are coming up after a watchdog-induced reset.  Some
     * BIOSes may clear this bit at bootup, preventing us from reporting
     * this case on such systems.  We clear this bit in ichwd_sts_reset().
     */
    if ((ichwd_read_tco_2(sc, TCO2_STS) & TCO_SECOND_TO_STS) != 0)
        device_printf(dev,
                      "resuming after hardware watchdog timeout\n");

    /* reset the watchdog status registers */
    ichwd_sts_reset(sc);

    /* make sure the WDT starts out inactive */
    ichwd_tmr_disable(sc);

    /* register the watchdog event handler */
    sc->ev_tag = EVENTHANDLER_REGISTER(watchdog_list, ichwd_event, sc, 0);

    /* disable the SMI handler */
    sc->smi_enabled = ichwd_smi_is_enabled(sc);
    ichwd_smi_disable(sc);

    return (0);
fail:
    sc = device_get_softc(dev);
    if (sc->tco_res != NULL)
        bus_release_resource(dev, SYS_RES_IOPORT,
                             sc->tco_rid, sc->tco_res);
    if (sc->smi_res != NULL)
        bus_release_resource(dev, SYS_RES_IOPORT,
                             sc->smi_rid, sc->smi_res);
    if (sc->gcs_res != NULL)
        bus_release_resource(ich, SYS_RES_MEMORY,
                             sc->gcs_rid, sc->gcs_res);

    return (ENXIO);
}