Exemple #1
0
/*
 * Attach the aubus.
 */
static void
aubus_attach(struct device *parent, struct device *self, void *aux)
{
	struct aubus_attach_args aa;
	struct device *sc = (struct device *)self;
	struct au_chipdep *chip;
	const struct au_dev *ad;
	int locs[AUBUSCF_NLOCS];

	printf("\n");

	chip = au_chipdep();
	KASSERT(chip != NULL);

	for (ad = chip->devices; ad->name != NULL; ad++) {
		aa.aa_name = ad->name;
		aa.aa_st = aubus_st;
		aa.aa_dt = &aubus_mdt;
		aubus_alloc_dma_tag(sc, aa.aa_dt);
		aa.aa_addrs[0] = ad->addr[0];
		aa.aa_addrs[1] = ad->addr[1];
		aa.aa_addrs[2] = ad->addr[2];
		aa.aa_irq[0] = ad->irq[0];
		aa.aa_irq[1] = ad->irq[1];

		locs[AUBUSCF_ADDR] = ad->addr[0];

		(void) config_found_sm_loc(self, "aubus", locs, &aa,
					   aubus_print, config_stdsubmatch);
	}
}
static void
mpbios_cpu(const uint8_t *ent, device_t self)
{
	const struct mpbios_proc *entry = (const struct mpbios_proc *)ent;
	struct cpu_attach_args caa;
	int locs[CPUBUSCF_NLOCS];

	/* XXX move this into the CPU attachment goo. */
	/* check for usability */
	if (!(entry->cpu_flags & PROCENTRY_FLAG_EN))
		return;

	mpbios_ncpu++;

	/* check for BSP flag */
	if (entry->cpu_flags & PROCENTRY_FLAG_BP)
		caa.cpu_role = CPU_ROLE_BP;
	else
		caa.cpu_role = CPU_ROLE_AP;

	caa.cpu_id = entry->apic_id;
	caa.cpu_number = entry->apic_id;
	caa.cpu_func = &mp_cpu_funcs;
	locs[CPUBUSCF_APID] = caa.cpu_number;

	config_found_sm_loc(self, "cpubus", locs, &caa, mp_cpuprint,
			    config_stdsubmatch);
}
Exemple #3
0
void
arbus_attach(struct device *parent, struct device *self, void *aux)
{
	struct arbus_attach_args aa;
	const struct ar531x_device *devices;
	int i;

	printf("\n");
	int locs[ARBUSCF_NLOCS];

	arbus_init();

	for (i = 0, devices = ar531x_get_devices(); devices[i].name; i++) {

		aa.aa_name = devices[i].name;
		aa.aa_size = devices[i].size;
		aa.aa_dmat = &arbus_mdt;
		aa.aa_bst = &arbus_mbst;
		aa.aa_cirq = devices[i].cirq;
		aa.aa_mirq = devices[i].mirq;
		aa.aa_addr = devices[i].addr;

		locs[ARBUSCF_ADDR] = aa.aa_addr;

		if (ar531x_enable_device(&devices[i]) != 0) {
			continue;
		}

		(void) config_found_sm_loc(self, "arbus", locs, &aa,
		    arbus_print, config_stdsubmatch);
	}
}
Exemple #4
0
/*
 * Attach the on-chip peripheral bus.
 */
static void
opb_attach(struct device *parent, struct device *self, void *aux)
{
	struct plb_attach_args *paa = aux;
	struct opb_attach_args oaa;
	bus_space_tag_t tag;
	int i, pvr;

	printf("\n");
	pvr = mfpvr() >> 16;

	tag = opb_get_bus_space_tag();

	for (i = 0; opb_devs[i].name != NULL; i++) {
		if (opb_devs[i].pvr != pvr)
			continue;
		oaa.opb_name = opb_devs[i].name;
		oaa.opb_addr = opb_devs[i].addr;
		oaa.opb_instance = opb_devs[i].instance;
		oaa.opb_irq = opb_devs[i].irq;
		oaa.opb_bt = tag;
		oaa.opb_dmat = paa->plb_dmat;

		(void) config_found_sm_loc(self, "opb", NULL, &oaa, opb_print,
					   opb_submatch);
	}
}
/*
 * attach a socket -- we don't know about irqs yet
 */
void
pcic_attach_socket(struct pcic_handle *h)
{
	struct pcmciabus_attach_args paa;
	struct pcic_softc *sc = device_private(h->ph_parent);
	int locs[PCMCIABUSCF_NLOCS];

	/* initialize the rest of the handle */

	h->shutdown = 0;
	h->memalloc = 0;
	h->ioalloc = 0;
	h->ih_irq = 0;

	/* now, config one pcmcia device per socket */

	paa.paa_busname = "pcmcia";
	paa.pct = (pcmcia_chipset_tag_t) sc->pct;
	paa.pch = (pcmcia_chipset_handle_t) h;

	locs[PCMCIABUSCF_CONTROLLER] = h->chip;
	locs[PCMCIABUSCF_SOCKET] = h->socket;

	h->pcmcia = config_found_sm_loc(sc->dev, "pcmciabus", locs, &paa,
					pcic_print, config_stdsubmatch);
	if (h->pcmcia == NULL) {
		h->flags &= ~PCIC_FLAG_SOCKETP;
		return;
	}

}
Exemple #6
0
void
mca_attach(device_t parent, device_t self, void *aux)
{
	struct mcabus_attach_args *mba = aux;
	bus_space_tag_t iot, memt;
	bus_dma_tag_t dmat;
	mca_chipset_tag_t mc;
	int slot;

	mca_attach_hook(parent, self, mba);
	aprint_naive("\n");
	aprint_normal("\n");

	iot = mba->mba_iot;
	memt = mba->mba_memt;
	mc = mba->mba_mc;
	dmat = mba->mba_dmat;

	/*
	 * Search for and attach subdevices.
	 *
	 * NB: In the adapter setup register, slots are numbered from 0,
	 * but officially they are numbered from 1.
	 * We use the former convention internally and the latter for text
	 * messages and in config files.
	 */

	for (slot = 0; slot < MCA_MAX_SLOTS; slot++) {
		struct mca_attach_args ma;
		int reg;
		int locs[MCACF_NLOCS];

		ma.ma_iot = iot;
		ma.ma_memt = memt;
		ma.ma_dmat = dmat;
		ma.ma_mc = mc;
		ma.ma_slot = slot;

		for(reg = 0; reg < 8; reg++)
			ma.ma_pos[reg]=mca_conf_read(mc, slot, reg);

		ma.ma_id = ma.ma_pos[0] + (ma.ma_pos[1] << 8);
		if (ma.ma_id == 0xffff)	/* no adapter here */
			continue;

		locs[MCACF_SLOT] = slot;

		if (ma.ma_pos[2] & MCA_POS2_ENABLE
		    || mca_match_disabled(ma.ma_id))
			config_found_sm_loc(self, "mca", locs, &ma,
					    mca_print, config_stdsubmatch);
		else {
			mca_print(&ma, device_xname(self));
			aprint_normal(" disabled\n");
		}
	}
}
Exemple #7
0
static void
mainbus_attach(device_t parent, device_t self, void *aux)
{
	struct mainbus_attach_args ma;
	const struct mainbusdev *md;
#if defined(PCI_NETBSD_ENABLE_IDE) || defined(PCI_NETBSD_CONFIGURE)
	struct malta_config *mcp = &malta_configuration;
	pci_chipset_tag_t pc = &mcp->mc_pc;
#endif
#if defined(PCI_NETBSD_ENABLE_IDE)
	pcitag_t idetag;
	pcireg_t idetim;
#endif

	mainbus_found = true;
	printf("\n");

#if defined(PCI_NETBSD_CONFIGURE)
	struct mips_cache_info * const mci = &mips_cache_info;

	struct extent *ioext = extent_create("pciio", 0x00001000, 0x0000efff,
	    NULL, 0, EX_NOWAIT);
	struct extent *memext = extent_create("pcimem", MALTA_PCIMEM1_BASE,
	    MALTA_PCIMEM1_BASE + MALTA_PCIMEM1_SIZE,
	    NULL, 0, EX_NOWAIT);

	pci_configure_bus(pc, ioext, memext, NULL, 0, mci->mci_dcache_align);
	extent_destroy(ioext);
	extent_destroy(memext);
#endif /* PCI_NETBSD_CONFIGURE */

#if defined(PCI_NETBSD_ENABLE_IDE)
	/*
	 * Perhaps PMON has not enabled the IDE controller.  Easy to
	 * fix -- just set the ENABLE bits for each channel in the
	 * IDETIM register.  Just clear all the bits for the channel
	 * except for the ENABLE bits -- the `pciide' driver will
	 * properly configure it later.
	 */
	idetim = 0;
	if (PCI_NETBSD_ENABLE_IDE & 0x01)
		idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE, 0);
	if (PCI_NETBSD_ENABLE_IDE & 0x02)
		idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE, 1);

	/* pciide0 is pci device 10, function 1 */
	idetag = pci_make_tag(pc, 0, 10, 1);
	pci_conf_write(pc, idetag, PIIX_IDETIM, idetim);
#endif
	for (md = mainbusdevs; md->md_name != NULL; md++) {
		ma.ma_name = md->md_name;
		ma.ma_addr = md->md_addr;
		ma.ma_intr = md->md_intr;
		(void) config_found_sm_loc(self, "mainbus", NULL, &ma,
		    mainbus_print, mainbus_submatch);
	}
}
static device_t
gsc_module_callback(device_t self, struct confargs *ca)
{
	struct gsc_softc *sc = device_private(self);
	struct gsc_attach_args ga;

	/* Make the GSC attach args. */
	ga = sc->sc_ga;
	ga.ga_ca = *ca;
	ga.ga_iot = sc->sc_ga.ga_iot;
	ga.ga_dmatag = sc->sc_ga.ga_dmatag;
	(*sc->sc_ga.ga_fix_args)(sc->sc_ga.ga_fix_args_cookie, &ga);

	return config_found_sm_loc(self, "gsc", NULL, &ga, mbprint, mbsubmatch);
}
Exemple #9
0
/*
 * Attach the on-chip peripheral bus.
 */
static void
opb_attach(device_t parent, device_t self, void *aux)
{
	struct opb_softc *sc = device_private(self);
	struct plb_attach_args *paa = aux;
	struct opb_attach_args oaa;
	int i, pvr;

	aprint_naive("\n");
	aprint_normal("\n");
	pvr = mfpvr() >> 16;

	sc->sc_dev = self;
	sc->sc_iot = opb_get_bus_space_tag();

	for (i = 0; opb_params[i].pvr != 0 && opb_params[i].pvr != pvr; i++)
		;
	if (opb_params[i].pvr == 0)
		panic("opb_get_bus_space_tag: no params for this CPU!");
	opb_get_frequency = opb_params[i].opb_get_frequency;
#ifdef EMAC_ZMII_PHY
	if (opb_params[i].zmii_base != 0)
		bus_space_map(sc->sc_iot, opb_params[i].zmii_base, ZMII0_SIZE,
		    0, &sc->sc_zmiih);
#endif
#ifdef EMAC_RGMII_PHY
	if (opb_params[i].rgmii_base != 0)
		bus_space_map(sc->sc_iot, opb_params[i].rgmii_base, RGMII0_SIZE,
		    0, &sc->sc_rgmiih);
#endif

	for (i = 0; opb_devs[i].name != NULL; i++) {
		if (opb_devs[i].pvr != pvr)
			continue;
		oaa.opb_name = opb_devs[i].name;
		oaa.opb_addr = opb_devs[i].addr;
		oaa.opb_instance = opb_devs[i].instance;
		oaa.opb_irq = opb_devs[i].irq;
		oaa.opb_bt = sc->sc_iot;
		oaa.opb_dmat = paa->plb_dmat;
		oaa.opb_flags = opb_devs[i].flags;

		(void) config_found_sm_loc(self, "opb", NULL, &oaa, opb_print,
					   opb_submatch);
	}
}
Exemple #10
0
static void
upc_found(struct upc_softc *sc, char const *devtype, int offset, int size,
	  struct upc_irqhandle *uih)
{
	struct upc_attach_args ua;
	int locs[UPCCF_NLOCS];

	ua.ua_devtype = devtype;
	ua.ua_offset = offset;
	ua.ua_iot = sc->sc_iot;
	bus_space_subregion(sc->sc_iot, sc->sc_ioh, offset, size, &ua.ua_ioh);
	ua.ua_irqhandle = uih;

	locs[UPCCF_OFFSET] = offset;

	config_found_sm_loc(&sc->sc_dev, "upc", locs, &ua,
			    upc_print, config_stdsubmatch);
}
Exemple #11
0
static usbd_status
usbd_attachwholedevice(device_t parent, struct usbd_device *dev, int port,
	int usegeneric)
{
	struct usb_attach_arg uaa;
	usb_device_descriptor_t *dd = &dev->ud_ddesc;
	device_t dv;
	int dlocs[USBDEVIFCF_NLOCS];

	uaa.uaa_device = dev;
	uaa.uaa_usegeneric = usegeneric;
	uaa.uaa_port = port;
	uaa.uaa_vendor = UGETW(dd->idVendor);
	uaa.uaa_product = UGETW(dd->idProduct);
	uaa.uaa_release = UGETW(dd->bcdDevice);
	uaa.uaa_class = dd->bDeviceClass;
	uaa.uaa_subclass = dd->bDeviceSubClass;
	uaa.uaa_proto = dd->bDeviceProtocol;

	dlocs[USBDEVIFCF_PORT] = uaa.uaa_port;
	dlocs[USBDEVIFCF_VENDOR] = uaa.uaa_vendor;
	dlocs[USBDEVIFCF_PRODUCT] = uaa.uaa_product;
	dlocs[USBDEVIFCF_RELEASE] = uaa.uaa_release;
	/* the rest is historical ballast */
	dlocs[USBDEVIFCF_CONFIGURATION] = -1;
	dlocs[USBDEVIFCF_INTERFACE] = -1;

	KERNEL_LOCK(1, NULL);
	dv = config_found_sm_loc(parent, "usbdevif", dlocs, &uaa, usbd_print,
				 config_stdsubmatch);
	KERNEL_UNLOCK_ONE(NULL);
	if (dv) {
		dev->ud_subdevs = kmem_alloc(sizeof(dv), KM_SLEEP);
		if (dev->ud_subdevs == NULL)
			return USBD_NOMEM;
		dev->ud_subdevs[0] = dv;
		dev->ud_subdevlen = 1;
		dev->ud_nifaces_claimed = 1; /* XXX */
		usbd_serialnumber(dv, dev);
	}
	return USBD_NORMAL_COMPLETION;
}
Exemple #12
0
static void
zbbus_attach(device_t parent, device_t self, void *aux)
{
	struct zbbus_attach_args za;
	int i;

	printf("\n");
	zbbus_attached = 1;

	sb1250_icu_init();

	for (i = 0; i < sb1250_zbbus_dev_count; i++) {
		memset(&za, 0, sizeof za);
		za.za_locs = sb1250_zbbus_devs[i];
		config_found_sm_loc(self, "zbbus", NULL, &za, zbbus_print,
				    zbbus_submatch);
	}

	return;
}
Exemple #13
0
int
cac_rescan(device_t self, const char *attr, const int *flags)
{
	struct cac_softc *sc;
	struct cac_attach_args caca;
	int locs[CACCF_NLOCS];
	int i;

	sc = device_private(self);
	for (i = 0; i < sc->sc_nunits; i++) {
		if (sc->sc_unitmask & (1 << i))
			continue;
		caca.caca_unit = i;

		locs[CACCF_UNIT] = i;

		if (config_found_sm_loc(self, attr, locs, &caca, cac_print,
			    config_stdsubmatch))
			sc->sc_unitmask |= 1 << i;
	}
	return 0;
}
Exemple #14
0
static void 
obio_attach(device_t parent, device_t self, void *aux)
{
	struct confargs *ca = aux;
	struct obio_softc *sc = device_private(self);
	struct confargs oba;
	int addr;

	obio_attached = 1;
	sc->sc_dev = self;

	aprint_normal("\n");

	sc->sc_bustag = ca->ca_bustag;
	sc->sc_dmatag = ca->ca_dmatag;

	obio_space_tag.cookie = sc;
	obio_space_tag.parent = sc->sc_bustag;

	obio_dma_tag = *sc->sc_dmatag;
	obio_dma_tag._cookie = sc;
	obio_dma_tag._dmamap_load = obio_dmamap_load;

	oba = *ca;
	oba.ca_bustag = &obio_space_tag;
	oba.ca_dmatag = &obio_dma_tag;

	/* Configure these in order of address. */
	for (addr = 0; addr < OBIO_END; addr += OBIO_INCR) {
		/* Our parent set ca->ca_bustype already. */
		oba.ca_paddr = addr;
		/* These are filled-in by obio_submatch. */
		oba.ca_intpri = -1;
		oba.ca_intvec = -1;
		(void)config_found_sm_loc(self, "obio", NULL, &oba, obio_print,
		    obio_submatch);
	}
}
Exemple #15
0
static device_t
at91bus_found(device_t self, bus_addr_t addr, int pid)
{
	int locs[AT91BUSCF_NLOCS];
	struct at91bus_attach_args sa;
	struct at91bus_softc *sc;

	memset(&locs, 0, sizeof(locs));
	memset(&sa, 0, sizeof(sa));

	locs[AT91BUSCF_ADDR] = addr;
	locs[AT91BUSCF_PID]  = pid;

	sc = device_private(self);
	sa.sa_iot = sc->sc_iot;
	sa.sa_dmat = sc->sc_dmat;
	sa.sa_addr = addr;
	sa.sa_size = 1;
	sa.sa_pid = pid;

	return config_found_sm_loc(self, "at91bus", locs, &sa,
				   at91bus_print, at91bus_submatch);
}
Exemple #16
0
void 
uftdi_attach(device_t parent, device_t self, void *aux)
{
	struct uftdi_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usbd_interface_handle iface;
	usb_device_descriptor_t *ddesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	const char *devname = device_xname(self);
	int i,idx;
	usbd_status err;
	struct ucom_attach_args uca;

	DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc));

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1);
	if (err) {
		aprint_error("\n%s: failed to set configuration, err=%s\n",
		       devname, usbd_errstr(err));
		goto bad;
	}

	sc->sc_dev = self;
	sc->sc_udev = dev;
	sc->sc_numports = 1;
	sc->sc_type = UFTDI_TYPE_8U232AM; /* most devices are post-8U232AM */
	sc->sc_hdrlen = 0;
	if (uaa->vendor == USB_VENDOR_FTDI
	    && uaa->product == USB_PRODUCT_FTDI_SERIAL_8U100AX) {
		sc->sc_type = UFTDI_TYPE_SIO;
		sc->sc_hdrlen = 1;
	}

	ddesc = usbd_get_device_descriptor(dev);
	sc->sc_chiptype = UGETW(ddesc->bcdDevice);
	switch (sc->sc_chiptype) {
	case 0x500: /* 2232D */
	case 0x700: /* 2232H */
		sc->sc_numports = 2;
		break;
	case 0x800: /* 4232H */
		sc->sc_numports = 4;
		break;
	case 0x200: /* 232/245AM */
	case 0x400: /* 232/245BL */
	case 0x600: /* 232/245R */
	default:
		break;
	}

	for (idx = UFTDI_IFACE_INDEX; idx < sc->sc_numports; idx++) {
		err = usbd_device2interface_handle(dev, idx, &iface);
		if (err) {
			aprint_error(
			    "\n%s: failed to get interface idx=%d, err=%s\n",
			    devname, idx, usbd_errstr(err));
			goto bad;
		}

		id = usbd_get_interface_descriptor(iface);

		sc->sc_iface[idx] = iface;

		uca.bulkin = uca.bulkout = -1;
		uca.ibufsize = uca.obufsize = 0;
		for (i = 0; i < id->bNumEndpoints; i++) {
			int addr, dir, attr;
			ed = usbd_interface2endpoint_descriptor(iface, i);
			if (ed == NULL) {
				aprint_error_dev(self,
				    "could not read endpoint descriptor: %s\n",
				    usbd_errstr(err));
				goto bad;
			}

			addr = ed->bEndpointAddress;
			dir = UE_GET_DIR(ed->bEndpointAddress);
			attr = ed->bmAttributes & UE_XFERTYPE;
			if (dir == UE_DIR_IN && attr == UE_BULK) {
				uca.bulkin = addr;
				uca.ibufsize = UGETW(ed->wMaxPacketSize);
				if (uca.ibufsize >= UFTDI_MAX_IBUFSIZE)
					uca.ibufsize = UFTDI_MAX_IBUFSIZE;
			} else if (dir == UE_DIR_OUT && attr == UE_BULK) {
				uca.bulkout = addr;
				uca.obufsize = UGETW(ed->wMaxPacketSize)
				    - sc->sc_hdrlen;
				if (uca.obufsize >= UFTDI_MAX_OBUFSIZE)
					uca.obufsize = UFTDI_MAX_OBUFSIZE;
				/* Limit length if we have a 6-bit header.  */
				if ((sc->sc_hdrlen > 0) &&
				    (uca.obufsize > UFTDIOBUFSIZE))
					uca.obufsize = UFTDIOBUFSIZE;
			} else {
				aprint_error_dev(self,
				    "unexpected endpoint\n");
				goto bad;
			}
		}
		if (uca.bulkin == -1) {
			aprint_error_dev(self,
			    "Could not find data bulk in\n");
			goto bad;
		}
		if (uca.bulkout == -1) {
			aprint_error_dev(self,
			    "Could not find data bulk out\n");
			goto bad;
		}

		uca.portno = FTDI_PIT_SIOA + idx;
		/* bulkin, bulkout set above */
		if (uca.ibufsize == 0)
			uca.ibufsize = UFTDIIBUFSIZE;
		uca.ibufsizepad = uca.ibufsize;
		if (uca.obufsize == 0)
			uca.obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen;
		uca.opkthdrlen = sc->sc_hdrlen;
		uca.device = dev;
		uca.iface = iface;
		uca.methods = &uftdi_methods;
		uca.arg = sc;
		uca.info = NULL;

		DPRINTF(("uftdi: in=0x%x out=0x%x isize=0x%x osize=0x%x\n",
			uca.bulkin, uca.bulkout,
			uca.ibufsize, uca.obufsize));
		sc->sc_subdev[idx] = config_found_sm_loc(self, "ucombus", NULL,
		    &uca, ucomprint, ucomsubmatch);
	}

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
			   sc->sc_dev);

	return;

bad:
	DPRINTF(("uftdi_attach: ATTACH ERROR\n"));
	sc->sc_dying = 1;
	return;
}
Exemple #17
0
void
uhidev_attach(device_t parent, device_t self, void *aux)
{
	struct uhidev_softc *sc = device_private(self);
	struct usbif_attach_arg *uiaa = aux;
	struct usbd_interface *iface = uiaa->uiaa_iface;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	struct uhidev_attach_arg uha;
	device_t dev;
	struct uhidev *csc;
	int maxinpktsize, size, nrepid, repid, repsz;
	int *repsizes;
	int i;
	void *desc;
	const void *descptr;
	usbd_status err;
	char *devinfop;
	int locs[UHIDBUSCF_NLOCS];

	sc->sc_dev = self;
	sc->sc_udev = uiaa->uiaa_device;
	sc->sc_iface = iface;

	aprint_naive("\n");
	aprint_normal("\n");

	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);

	id = usbd_get_interface_descriptor(iface);

	devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0);
	aprint_normal_dev(self, "%s, iclass %d/%d\n",
	       devinfop, id->bInterfaceClass, id->bInterfaceSubClass);
	usbd_devinfo_free(devinfop);

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");

	(void)usbd_set_idle(iface, 0, 0);
#if 0

	if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_NO_SET_PROTO) == 0 &&
	    id->bInterfaceSubClass != UISUBCLASS_BOOT)
		(void)usbd_set_protocol(iface, 1);
#endif

	maxinpktsize = 0;
	sc->sc_iep_addr = sc->sc_oep_addr = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(iface, i);
		if (ed == NULL) {
			aprint_error_dev(self,
			    "could not read endpoint descriptor\n");
			sc->sc_dying = 1;
			return;
		}

		DPRINTFN(10,("uhidev_attach: bLength=%d bDescriptorType=%d "
		    "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
		    " bInterval=%d\n",
		    ed->bLength, ed->bDescriptorType,
		    ed->bEndpointAddress & UE_ADDR,
		    UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
		    ed->bmAttributes & UE_XFERTYPE,
		    UGETW(ed->wMaxPacketSize), ed->bInterval));

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
			maxinpktsize = UGETW(ed->wMaxPacketSize);
			sc->sc_iep_addr = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
			sc->sc_oep_addr = ed->bEndpointAddress;
		} else {
			aprint_verbose_dev(self, "endpoint %d: ignored\n", i);
		}
	}

	/*
	 * Check that we found an input interrupt endpoint. The output interrupt
	 * endpoint is optional
	 */
	if (sc->sc_iep_addr == -1) {
		aprint_error_dev(self, "no input interrupt endpoint\n");
		sc->sc_dying = 1;
		return;
	}

	/* XXX need to extend this */
	descptr = NULL;
	if (uiaa->uiaa_vendor == USB_VENDOR_WACOM) {
		static uByte reportbuf[] = {2, 2, 2};

		/* The report descriptor for the Wacom Graphire is broken. */
		switch (uiaa->uiaa_product) {
		case USB_PRODUCT_WACOM_GRAPHIRE:
		case USB_PRODUCT_WACOM_GRAPHIRE2:
		case USB_PRODUCT_WACOM_GRAPHIRE3_4X5:
		case USB_PRODUCT_WACOM_GRAPHIRE3_6X8:
		case USB_PRODUCT_WACOM_GRAPHIRE4_4X5: /* The 6x8 too? */
			/*
			 * The Graphire3 needs 0x0202 to be written to
			 * feature report ID 2 before it'll start
			 * returning digitizer data.
			 */
			usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 2,
			    &reportbuf, sizeof(reportbuf));

			size = sizeof(uhid_graphire3_4x5_report_descr);
			descptr = uhid_graphire3_4x5_report_descr;
			break;
		default:
			/* Keep descriptor */
			break;
		}
	}
	if (USBIF_IS_XINPUT(uiaa)) {
		size = sizeof(uhid_xinput_report_descr);
		descptr = uhid_xinput_report_descr;
	}
	if (USBIF_IS_X1INPUT(uiaa)) {
		sc->sc_flags |= UHIDEV_F_XB1;
		size = sizeof(uhid_x1input_report_descr);
		descptr = uhid_x1input_report_descr;
	}

	if (descptr) {
		desc = kmem_alloc(size, KM_SLEEP);
		if (desc == NULL)
			err = USBD_NOMEM;
		else {
			err = USBD_NORMAL_COMPLETION;
			memcpy(desc, descptr, size);
		}
	} else {
		desc = NULL;
		err = usbd_read_report_desc(uiaa->uiaa_iface, &desc, &size);
	}
	if (err) {
		aprint_error_dev(self, "no report descriptor\n");
		sc->sc_dying = 1;
		return;
	}

	if (uiaa->uiaa_vendor == USB_VENDOR_HOSIDEN &&
	    uiaa->uiaa_product == USB_PRODUCT_HOSIDEN_PPP) {
		static uByte reportbuf[] = { 1 };
		/*
		 *  This device was sold by Konami with its ParaParaParadise
		 *  game for PlayStation2.  It needs to be "turned on"
		 *  before it will send any reports.
		 */

		usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 0,
		    &reportbuf, sizeof(reportbuf));
	}

	if (uiaa->uiaa_vendor == USB_VENDOR_LOGITECH &&
	    uiaa->uiaa_product == USB_PRODUCT_LOGITECH_CBT44 && size == 0xb1) {
		uint8_t *data = desc;
		/*
		 * This device has a odd USAGE_MINIMUM value that would
		 * cause the multimedia keys to have their usage number
		 * shifted up one usage.  Adjust so the usages are sane.
		 */

		if (data[0x56] == 0x19 && data[0x57] == 0x01 &&
		    data[0x58] == 0x2a && data[0x59] == 0x8c)
			data[0x57] = 0x00;
	}

	/*
	 * Enable the Six Axis and DualShock 3 controllers.
	 * See http://ps3.jim.sh/sixaxis/usb/
	 */
	if (uiaa->uiaa_vendor == USB_VENDOR_SONY &&
	    uiaa->uiaa_product == USB_PRODUCT_SONY_PS3CONTROLLER) {
		usb_device_request_t req;
		char data[17];
		int actlen;

		req.bmRequestType = UT_READ_CLASS_INTERFACE;
		req.bRequest = 1;
		USETW(req.wValue, 0x3f2);
		USETW(req.wIndex, 0);
		USETW(req.wLength, sizeof(data));

		usbd_do_request_flags(sc->sc_udev, &req, data,
			USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
	}

	sc->sc_repdesc = desc;
	sc->sc_repdesc_size = size;

	uha.uiaa = uiaa;
	nrepid = uhidev_maxrepid(desc, size);
	if (nrepid < 0)
		return;
	if (nrepid > 0)
		aprint_normal_dev(self, "%d report ids\n", nrepid);
	nrepid++;
	repsizes = kmem_alloc(nrepid * sizeof(*repsizes), KM_SLEEP);
	if (repsizes == NULL)
		goto nomem;
	sc->sc_subdevs = kmem_zalloc(nrepid * sizeof(device_t),
	    KM_SLEEP);
	if (sc->sc_subdevs == NULL) {
		kmem_free(repsizes, nrepid * sizeof(*repsizes));
nomem:
		aprint_error_dev(self, "no memory\n");
		return;
	}

	/* Just request max packet size for the interrupt pipe */
	sc->sc_isize = maxinpktsize;
	sc->sc_nrepid = nrepid;

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);

	for (repid = 0; repid < nrepid; repid++) {
		repsz = hid_report_size(desc, size, hid_input, repid);
		DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz));
		repsizes[repid] = repsz;
	}

	DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));

	uha.parent = sc;
	for (repid = 0; repid < nrepid; repid++) {
		DPRINTF(("uhidev_match: try repid=%d\n", repid));
		if (hid_report_size(desc, size, hid_input, repid) == 0 &&
		    hid_report_size(desc, size, hid_output, repid) == 0 &&
		    hid_report_size(desc, size, hid_feature, repid) == 0) {
			;	/* already NULL in sc->sc_subdevs[repid] */
		} else {
			uha.reportid = repid;
			locs[UHIDBUSCF_REPORTID] = repid;

			dev = config_found_sm_loc(self,
				"uhidbus", locs, &uha,
				uhidevprint, config_stdsubmatch);
			sc->sc_subdevs[repid] = dev;
			if (dev != NULL) {
				csc = device_private(dev);
				csc->sc_in_rep_size = repsizes[repid];
#ifdef DIAGNOSTIC
				DPRINTF(("uhidev_match: repid=%d dev=%p\n",
					 repid, dev));
				if (csc->sc_intr == NULL) {
					kmem_free(repsizes,
					    nrepid * sizeof(*repsizes));
					aprint_error_dev(self,
					    "sc_intr == NULL\n");
					return;
				}
#endif
				rnd_attach_source(&csc->rnd_source,
						  device_xname(dev),
						  RND_TYPE_TTY,
						  RND_FLAG_DEFAULT);
			}
		}
	}
	kmem_free(repsizes, nrepid * sizeof(*repsizes));

	return;
}
Exemple #18
0
void 
moscom_attach(device_t parent, device_t self, void *aux)
{
	struct moscom_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	struct ucom_attach_args uca;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	usbd_status error;
	int i;

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

	sc->sc_dev = self;

	bzero(&uca, sizeof(uca));
	sc->sc_udev = uaa->device;

	if (usbd_set_config_index(sc->sc_udev, MOSCOM_CONFIG_NO, 1) != 0) {
		aprint_error_dev(self, "could not set configuration no\n");
		sc->sc_dying = 1;
		return;
	}

	/* get the first interface handle */
	error = usbd_device2interface_handle(sc->sc_udev, MOSCOM_IFACE_NO,
	    &sc->sc_iface);
	if (error != 0) {
		aprint_error_dev(self, "could not get interface handle\n");
		sc->sc_dying = 1;
		return;
	}

	id = usbd_get_interface_descriptor(sc->sc_iface);

	uca.bulkin = uca.bulkout = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			aprint_error_dev(self,
			    "no endpoint descriptor found for %d\n", i);
			sc->sc_dying = 1;
			return;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
			uca.bulkin = ed->bEndpointAddress;
		else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
			uca.bulkout = ed->bEndpointAddress;
	}

	if (uca.bulkin == -1 || uca.bulkout == -1) {
		aprint_error_dev(self, "missing endpoint\n");
		sc->sc_dying = 1;
		return;
	}

	uca.ibufsize = MOSCOMBUFSZ;
	uca.obufsize = MOSCOMBUFSZ;
	uca.ibufsizepad = MOSCOMBUFSZ;
	uca.opkthdrlen = 0;
	uca.device = sc->sc_udev;
	uca.iface = sc->sc_iface;
	uca.methods = &moscom_methods;
	uca.arg = sc;
	uca.info = NULL;

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
	    sc->sc_dev);
	
	sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca,
					    ucomprint, ucomsubmatch);

	return;
}
Exemple #19
0
static void
eisaattach(device_t parent, device_t self, void *aux)
{
	struct eisabus_attach_args *eba = aux;
	bus_space_tag_t iot, memt;
	bus_dma_tag_t dmat;
	eisa_chipset_tag_t ec;
	int slot, maxnslots;

	eisa_attach_hook(parent, self, eba);
	printf("\n");

	iot = eba->eba_iot;
	memt = eba->eba_memt;
	ec = eba->eba_ec;
	dmat = eba->eba_dmat;

	/*
	 * Search for and attach subdevices.
	 *
	 * Slot 0 is the "motherboard" slot, and the code attaching
	 * the EISA bus should have already attached an ISA bus there.
	 */
	maxnslots = eisa_maxslots(ec);
	for (slot = 1; slot < maxnslots; slot++) {
		struct eisa_attach_args ea;
		u_int slotaddr;
		bus_space_handle_t slotioh;
		int i;
		int locs[EISACF_NLOCS];

		ea.ea_iot = iot;
		ea.ea_memt = memt;
		ea.ea_ec = ec;
		ea.ea_dmat = dmat;
		ea.ea_slot = slot;
		slotaddr = EISA_SLOT_ADDR(slot);

		/*
		 * Get a mapping for the whole slot-specific address
		 * space.  If we can't, assume nothing's there but warn
		 * about it.
		 */
		if (bus_space_map(iot, slotaddr, EISA_SLOT_SIZE, 0, &slotioh)) {
			aprint_error_dev(self,
			    "can't map I/O space for slot %d\n", slot);
			continue;
		}

		/* Get the vendor ID bytes */
		for (i = 0; i < EISA_NVIDREGS; i++)
			ea.ea_vid[i] = bus_space_read_1(iot, slotioh,
			    EISA_SLOTOFF_VID + i);

		/* Check for device existence */
		if (EISA_VENDID_NODEV(ea.ea_vid)) {
#if 0
			printf("no device at %s slot %d\n", device_xname(self),
			    slot);
			printf("\t(0x%x, 0x%x)\n", ea.ea_vid[0], ea.ea_vid[1]);
#endif
			bus_space_unmap(iot, slotioh, EISA_SLOT_SIZE);
			continue;
		}

		/* And check that the firmware didn't biff something badly */
		if (EISA_VENDID_IDDELAY(ea.ea_vid)) {
			printf("%s slot %d not configured by BIOS?\n",
			    device_xname(self), slot);
			bus_space_unmap(iot, slotioh, EISA_SLOT_SIZE);
			continue;
		}

		/* Get the product ID bytes */
		for (i = 0; i < EISA_NPIDREGS; i++)
			ea.ea_pid[i] = bus_space_read_1(iot, slotioh,
			    EISA_SLOTOFF_PID + i);

		/* Create the ID string from the vendor and product IDs */
		ea.ea_idstring[0] = EISA_VENDID_0(ea.ea_vid);
		ea.ea_idstring[1] = EISA_VENDID_1(ea.ea_vid);
		ea.ea_idstring[2] = EISA_VENDID_2(ea.ea_vid);
		ea.ea_idstring[3] = EISA_PRODID_0(ea.ea_pid);
		ea.ea_idstring[4] = EISA_PRODID_1(ea.ea_pid);
		ea.ea_idstring[5] = EISA_PRODID_2(ea.ea_pid);
		ea.ea_idstring[6] = EISA_PRODID_3(ea.ea_pid);
		ea.ea_idstring[7] = '\0';		/* sanity */

		/* We no longer need the I/O handle; free it. */
		bus_space_unmap(iot, slotioh, EISA_SLOT_SIZE);

		locs[EISACF_SLOT] = slot;

		/* Attach matching device. */
		config_found_sm_loc(self, "eisa", locs, &ea,
				    eisaprint, config_stdsubmatch);
	}
}
Exemple #20
0
int
pci_probe_device(struct pci_softc *sc, pcitag_t tag,
    int (*match)(const struct pci_attach_args *),
    struct pci_attach_args *pap)
{
	pci_chipset_tag_t pc = sc->sc_pc;
	struct pci_attach_args pa;
	pcireg_t id, /* csr, */ pciclass, intr, bhlcr, bar, endbar;
#ifdef __HAVE_PCI_MSI_MSIX
	pcireg_t cap;
	int off;
#endif
	int ret, pin, bus, device, function, i, width;
	int locs[PCICF_NLOCS];

	pci_decompose_tag(pc, tag, &bus, &device, &function);

	/* a driver already attached? */
	if (sc->PCI_SC_DEVICESC(device, function).c_dev != NULL && !match)
		return 0;

	bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
	if (PCI_HDRTYPE_TYPE(bhlcr) > 2)
		return 0;

	id = pci_conf_read(pc, tag, PCI_ID_REG);
	/* csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); */
	pciclass = pci_conf_read(pc, tag, PCI_CLASS_REG);

	/* Invalid vendor ID value? */
	if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
		return 0;
	/* XXX Not invalid, but we've done this ~forever. */
	if (PCI_VENDOR(id) == 0)
		return 0;

	/* Collect memory range info */
	memset(sc->PCI_SC_DEVICESC(device, function).c_range, 0,
	    sizeof(sc->PCI_SC_DEVICESC(device, function).c_range));
	i = 0;
	switch (PCI_HDRTYPE_TYPE(bhlcr)) {
	case PCI_HDRTYPE_PPB:
		endbar = PCI_MAPREG_PPB_END;
		break;
	case PCI_HDRTYPE_PCB:
		endbar = PCI_MAPREG_PCB_END;
		break;
	default:
		endbar = PCI_MAPREG_END;
		break;
	}
	for (bar = PCI_MAPREG_START; bar < endbar; bar += width) {
		struct pci_range *r;
		pcireg_t type;

		width = 4;
		if (pci_mapreg_probe(pc, tag, bar, &type) == 0)
			continue;

		if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_MEM) {
			if (PCI_MAPREG_MEM_TYPE(type) ==
			    PCI_MAPREG_MEM_TYPE_64BIT)
				width = 8;

			r = &sc->PCI_SC_DEVICESC(device, function).c_range[i++];
			if (pci_mapreg_info(pc, tag, bar, type,
			    &r->r_offset, &r->r_size, &r->r_flags) != 0)
				break;
			if ((PCI_VENDOR(id) == PCI_VENDOR_ATI) && (bar == 0x10)
			    && (r->r_size == 0x1000000)) {
				struct pci_range *nr;
				/*
				 * this has to be a mach64
				 * split things up so each half-aperture can
				 * be mapped PREFETCHABLE except the last page
				 * which may contain registers
				 */
				r->r_size = 0x7ff000;
				r->r_flags = BUS_SPACE_MAP_LINEAR |
					     BUS_SPACE_MAP_PREFETCHABLE;
				nr = &sc->PCI_SC_DEVICESC(device,
				    function).c_range[i++];
				nr->r_offset = r->r_offset + 0x800000;
				nr->r_size = 0x7ff000;
				nr->r_flags = BUS_SPACE_MAP_LINEAR |
					      BUS_SPACE_MAP_PREFETCHABLE;
			}
			
		}
	}

	pa.pa_iot = sc->sc_iot;
	pa.pa_memt = sc->sc_memt;
	pa.pa_dmat = sc->sc_dmat;
	pa.pa_dmat64 = sc->sc_dmat64;
	pa.pa_pc = pc;
	pa.pa_bus = bus;
	pa.pa_device = device;
	pa.pa_function = function;
	pa.pa_tag = tag;
	pa.pa_id = id;
	pa.pa_class = pciclass;

	/*
	 * Set up memory, I/O enable, and PCI command flags
	 * as appropriate.
	 */
	pa.pa_flags = sc->sc_flags;

	/*
	 * If the cache line size is not configured, then
	 * clear the MRL/MRM/MWI command-ok flags.
	 */
	if (PCI_CACHELINE(bhlcr) == 0) {
		pa.pa_flags &= ~(PCI_FLAGS_MRL_OKAY|
		    PCI_FLAGS_MRM_OKAY|PCI_FLAGS_MWI_OKAY);
	}

	if (sc->sc_bridgetag == NULL) {
		pa.pa_intrswiz = 0;
		pa.pa_intrtag = tag;
	} else {
		pa.pa_intrswiz = sc->sc_intrswiz + device;
		pa.pa_intrtag = sc->sc_intrtag;
	}

	intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);

	pin = PCI_INTERRUPT_PIN(intr);
	pa.pa_rawintrpin = pin;
	if (pin == PCI_INTERRUPT_PIN_NONE) {
		/* no interrupt */
		pa.pa_intrpin = 0;
	} else {
		/*
		 * swizzle it based on the number of busses we're
		 * behind and our device number.
		 */
		pa.pa_intrpin = 	/* XXX */
		    ((pin + pa.pa_intrswiz - 1) % 4) + 1;
	}
	pa.pa_intrline = PCI_INTERRUPT_LINE(intr);

#ifdef __HAVE_PCI_MSI_MSIX
	if (pci_get_ht_capability(pc, tag, PCI_HT_CAP_MSIMAP, &off, &cap)) {
		/*
		 * XXX Should we enable MSI mapping ourselves on
		 * systems that have it disabled?
		 */
		if (cap & PCI_HT_MSI_ENABLED) {
			uint64_t addr;
			if ((cap & PCI_HT_MSI_FIXED) == 0) {
				addr = pci_conf_read(pc, tag,
				    off + PCI_HT_MSI_ADDR_LO);
				addr |= (uint64_t)pci_conf_read(pc, tag,
				    off + PCI_HT_MSI_ADDR_HI) << 32;
			} else
				addr = PCI_HT_MSI_FIXED_ADDR;

			/*
			 * XXX This will fail to enable MSI on systems
			 * that don't use the canonical address.
			 */
			if (addr == PCI_HT_MSI_FIXED_ADDR) {
				pa.pa_flags |= PCI_FLAGS_MSI_OKAY;
				pa.pa_flags |= PCI_FLAGS_MSIX_OKAY;
			}
		}
	}
#endif

	if (match != NULL) {
		ret = (*match)(&pa);
		if (ret != 0 && pap != NULL)
			*pap = pa;
	} else {
		struct pci_child *c;
		locs[PCICF_DEV] = device;
		locs[PCICF_FUNCTION] = function;

		c = &sc->PCI_SC_DEVICESC(device, function);
		pci_conf_capture(pc, tag, &c->c_conf);
		if (pci_get_powerstate(pc, tag, &c->c_powerstate) == 0)
			c->c_psok = true;
		else
			c->c_psok = false;

		c->c_dev = config_found_sm_loc(sc->sc_dev, "pci", locs, &pa,
					     pciprint, config_stdsubmatch);

		ret = (c->c_dev != NULL);
	}

	return ret;
}
Exemple #21
0
void
sab_attach(struct device *parent, struct device *self, void *aux)
{
	struct sab_softc *sc = (struct sab_softc *)self;
	struct ebus_attach_args *ea = aux;
	uint8_t r;
	u_int i;
	int locs[SABCF_NLOCS];

	sc->sc_bt = ea->ea_bustag;
	sc->sc_node = ea->ea_node;

	/* Use prom mapping, if available. */
	if (ea->ea_nvaddr)
		sparc_promaddr_to_handle(sc->sc_bt, ea->ea_vaddr[0],
		    &sc->sc_bh);
	else if (bus_space_map(sc->sc_bt, EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
				 ea->ea_reg[0].size, 0, &sc->sc_bh) != 0) {
		printf(": can't map register space\n");
		return;
	}

	sc->sc_ih = bus_intr_establish(ea->ea_bustag, ea->ea_intr[0],
	    IPL_TTY, sab_intr, sc);
	if (sc->sc_ih == NULL) {
		printf(": can't map interrupt\n");
		return;
	}

	sc->sc_softintr = softint_establish(SOFTINT_SERIAL, sab_softintr, sc);
	if (sc->sc_softintr == NULL) {
		printf(": can't get soft intr\n");
		return;
	}

	aprint_normal(": rev ");
	r = SAB_READ(sc, SAB_VSTR) & SAB_VSTR_VMASK;
	switch (r) {
	case SAB_VSTR_V_1:
		aprint_normal("1");
		break;
	case SAB_VSTR_V_2:
		aprint_normal("2");
		break;
	case SAB_VSTR_V_32:
		aprint_normal("3.2");
		break;
	default:
		aprint_normal("unknown(0x%x)", r);
		break;
	}
	aprint_normal("\n");

	/* Let current output drain */
	DELAY(100000);

	/* Set all pins, except DTR pins to be inputs */
	SAB_WRITE(sc, SAB_PCR, ~(SAB_PVR_DTR_A | SAB_PVR_DTR_B));
	/* Disable port interrupts */
	SAB_WRITE(sc, SAB_PIM, 0xff);
	SAB_WRITE(sc, SAB_PVR, SAB_PVR_DTR_A | SAB_PVR_DTR_B | SAB_PVR_MAGIC);
	SAB_WRITE(sc, SAB_IPC, SAB_IPC_ICPL);

	for (i = 0; i < SAB_NCHAN; i++) {
		struct sabtty_attach_args stax;

		stax.sbt_portno = i;

		locs[SABCF_CHANNEL] = i;

		sc->sc_child[i] =
		    (struct sabtty_softc *)config_found_sm_loc(self,
		     "sab", locs, &stax, sab_print, config_stdsubmatch);
		if (sc->sc_child[i] != NULL)
			sc->sc_nchild++;
	}
}
Exemple #22
0
void 
uipaq_attach(device_t parent, device_t self, void *aux)
{
	struct uipaq_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usbd_interface_handle iface;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	const char *devname = device_xname(self);
	int i;
	usbd_status err;
	struct ucom_attach_args uca;

	DPRINTFN(10,("\nuipaq_attach: sc=%p\n", sc));

	sc->sc_dev = self;

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

	/* Move the device into the configured state. */
	err = usbd_set_config_no(dev, UIPAQ_CONFIG_NO, 1);
	if (err) {
		aprint_error_dev(self, "failed to set configuration"
		    ", err=%s\n", usbd_errstr(err));
		goto bad;
	}

	err = usbd_device2interface_handle(dev, UIPAQ_IFACE_INDEX, &iface);
	if (err) {
		aprint_error("\n%s: failed to get interface, err=%s\n",
		    devname, usbd_errstr(err));
		goto bad;
	}

	sc->sc_flags = uipaq_lookup(uaa->vendor, uaa->product)->uv_flags;

	id = usbd_get_interface_descriptor(iface);

	sc->sc_udev = dev;
	sc->sc_iface = iface;

	uca.ibufsize = UIPAQIBUFSIZE;
	uca.obufsize = UIPAQOBUFSIZE;
	uca.ibufsizepad = UIPAQIBUFSIZE;
	uca.opkthdrlen = 0;
	uca.device = dev;
	uca.iface = iface;
	uca.methods = &uipaq_methods;
	uca.arg = sc;
	uca.portno = UCOM_UNK_PORTNO;
	uca.info = "Generic";

/*	err = uipaq_init(sc);
	if (err) {
		printf("%s: init failed, %s\n", device_xname(sc->sc_dev),
		    usbd_errstr(err));
		goto bad;
	}*/

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
	    sc->sc_dev);

	uca.bulkin = uca.bulkout = -1;
	for (i=0; i<id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(iface, i);
		if (ed == NULL) {
			aprint_error_dev(self,
			    "no endpoint descriptor for %d\n", i);
			goto bad;
		}
		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
			uca.bulkin = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
		}
	}
	if (uca.bulkin == -1 || uca.bulkout == -1) {
		aprint_error_dev(self, "no proper endpoints found (%d,%d) \n",
		    uca.bulkin, uca.bulkout);
		return;
	}

	sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca,
					    ucomprint, ucomsubmatch);

	return;

bad:
	DPRINTF(("uipaq_attach: ATTACH ERROR\n"));
	sc->sc_dying = 1;
	return;
}
static void
puc_attach(device_t parent, device_t self, void *aux)
{
	struct puc_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct puc_attach_args paa;
	pci_intr_handle_t intrhandle;
	pcireg_t subsys;
	int i, barindex;
	bus_addr_t base;
	bus_space_tag_t tag;
#ifdef PUCCN
	bus_space_handle_t ioh;
#endif
	int locs[PUCCF_NLOCS];

	subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	sc->sc_desc = puc_find_description(PCI_VENDOR(pa->pa_id),
	    PCI_PRODUCT(pa->pa_id), PCI_VENDOR(subsys), PCI_PRODUCT(subsys));
	if (sc->sc_desc == NULL) {
		/*
		 * This was a class/subclass match, so tell people to compile
		 * kernel with options that cause this driver to spew.
		 */
#ifdef PUC_PRINT_REGS
		printf(":\n");
		pci_conf_print(pa->pa_pc, pa->pa_tag, NULL);
#else
		printf(": unknown PCI communications device\n");
		printf("%s: compile kernel with PUC_PRINT_REGS and larger\n",
		    device_xname(self));
		printf("%s: mesage buffer (via 'options MSGBUFSIZE=...'),\n",
		    device_xname(self));
		printf("%s: and report the result with send-pr\n",
		    device_xname(self));
#endif
		return;
	}

	printf(": %s (", sc->sc_desc->name);
	for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++)
		printf("%s%s", i ? ", " : "",
		    puc_port_type_name(sc->sc_desc->ports[i].type));
	printf(")\n");

	for (i = 0; i < 6; i++) {
		pcireg_t bar, type;

		sc->sc_bar_mappings[i].mapped = 0;

		bar = pci_conf_read(pa->pa_pc, pa->pa_tag,
		    PCI_MAPREG_START + 4 * i);	/* XXX const */
		if (bar == 0)			/* BAR not implemented(?) */
			continue;

		type = (PCI_MAPREG_TYPE(bar) == PCI_MAPREG_TYPE_IO ?
		    PCI_MAPREG_TYPE_IO : PCI_MAPREG_MEM_TYPE(bar));

		if (type == PCI_MAPREG_TYPE_IO) {
			tag = pa->pa_iot;
			base =  PCI_MAPREG_IO_ADDR(bar);
		} else {
			tag = pa->pa_memt;
			base =  PCI_MAPREG_MEM_ADDR(bar);
		}
#ifdef PUCCN
		if (com_is_console(tag, base, &ioh)) {
			sc->sc_bar_mappings[i].mapped = 1;
			sc->sc_bar_mappings[i].a = base;
			sc->sc_bar_mappings[i].s = COM_NPORTS;
			sc->sc_bar_mappings[i].t = tag;
			sc->sc_bar_mappings[i].h = ioh;
			continue;
		}
#endif
		sc->sc_bar_mappings[i].mapped = (pci_mapreg_map(pa,
		    PCI_MAPREG_START + 4 * i, type, 0,
		    &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
		    &sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s)
		      == 0);
		if (sc->sc_bar_mappings[i].mapped)
			continue;

		aprint_error_dev(self, "couldn't map BAR at offset 0x%lx\n",
		    (long)(PCI_MAPREG_START + 4 * i));
	}

	/* Map interrupt. */
	if (pci_intr_map(pa, &intrhandle)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	/*
	 * XXX the sub-devices establish the interrupts, for the
	 * XXX following reasons:
	 * XXX
	 * XXX    * we can't really know what IPLs they'd want
	 * XXX
	 * XXX    * the MD dispatching code can ("should") dispatch
	 * XXX      chained interrupts better than we can.
	 * XXX
	 * XXX It would be nice if we could indicate to the MD interrupt
	 * XXX handling code that the interrupt line used by the device
	 * XXX was a PCI (level triggered) interrupt.
	 * XXX
	 * XXX It's not pretty, but hey, what is?
	 */

	/* Configure each port. */
	for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) {
		bus_space_handle_t subregion_handle;

		/* make sure the base address register is mapped */
		barindex = PUC_PORT_BAR_INDEX(sc->sc_desc->ports[i].bar);
		if (!sc->sc_bar_mappings[barindex].mapped) {
			printf("%s: %s port uses unmapped BAR (0x%x)\n",
			    device_xname(self),
			    puc_port_type_name(sc->sc_desc->ports[i].type),
			    sc->sc_desc->ports[i].bar);
			continue;
		}

		/* set up to configure the child device */
		paa.port = i;
		paa.type = sc->sc_desc->ports[i].type;
		paa.flags = sc->sc_desc->ports[i].flags;
		paa.pc = pa->pa_pc;
		paa.tag = pa->pa_tag;
		paa.intrhandle = intrhandle;
		paa.a = sc->sc_bar_mappings[barindex].a;
		paa.t = sc->sc_bar_mappings[barindex].t;
		paa.dmat = pa->pa_dmat;
		paa.dmat64 = pa->pa_dmat64;

		if (
#ifdef PUCCN
		    !com_is_console(sc->sc_bar_mappings[barindex].t,
		    sc->sc_bar_mappings[barindex].a, &subregion_handle)
		   &&
#endif
		    bus_space_subregion(sc->sc_bar_mappings[barindex].t,
		    sc->sc_bar_mappings[barindex].h,
		    sc->sc_desc->ports[i].offset,
		    sc->sc_bar_mappings[barindex].s -
		      sc->sc_desc->ports[i].offset,
		    &subregion_handle) != 0) {
			aprint_error_dev(self, "couldn't get subregion for port %d\n", i);
			continue;
		}
		paa.h = subregion_handle;

#if 0
		printf("%s: port %d: %s @ (index %d) 0x%x (0x%lx, 0x%lx)\n",
		    device_xname(self), paa.port,
		    puc_port_type_name(paa.type), barindex, (int)paa.a,
		    (long)paa.t, (long)paa.h);
#endif

		locs[PUCCF_PORT] = i;

		/* and configure it */
		sc->sc_ports[i].dev = config_found_sm_loc(self, "puc", locs,
			&paa, puc_print, config_stdsubmatch);
	}
}
Exemple #24
0
static usbd_status
usbd_attachinterfaces(device_t parent, struct usbd_device *dev,
		      int port, const int *locators)
{
	USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
	struct usbif_attach_arg uiaa;
	int ilocs[USBIFIFCF_NLOCS];
	usb_device_descriptor_t *dd = &dev->ud_ddesc;
	int nifaces;
	struct usbd_interface **ifaces;
	int i, j, loc;
	device_t dv;

	nifaces = dev->ud_cdesc->bNumInterface;
	ifaces = kmem_zalloc(nifaces * sizeof(*ifaces), KM_SLEEP);
	if (!ifaces)
		return USBD_NOMEM;
	for (i = 0; i < nifaces; i++) {
		if (!dev->ud_subdevs[i]) {
			ifaces[i] = &dev->ud_ifaces[i];
		}
		DPRINTF("interface %d %p", i, ifaces[i], 0, 0);
	}


	uiaa.uiaa_device = dev;
	uiaa.uiaa_port = port;
	uiaa.uiaa_vendor = UGETW(dd->idVendor);
	uiaa.uiaa_product = UGETW(dd->idProduct);
	uiaa.uiaa_release = UGETW(dd->bcdDevice);
	uiaa.uiaa_configno = dev->ud_cdesc->bConfigurationValue;
	uiaa.uiaa_ifaces = ifaces;
	uiaa.uiaa_nifaces = nifaces;
	ilocs[USBIFIFCF_PORT] = uiaa.uiaa_port;
	ilocs[USBIFIFCF_VENDOR] = uiaa.uiaa_vendor;
	ilocs[USBIFIFCF_PRODUCT] = uiaa.uiaa_product;
	ilocs[USBIFIFCF_RELEASE] = uiaa.uiaa_release;
	ilocs[USBIFIFCF_CONFIGURATION] = uiaa.uiaa_configno;

	for (i = 0; i < nifaces; i++) {
		if (!ifaces[i]) {
			DPRINTF("interface %d claimed", i, 0, 0, 0);
			continue; /* interface already claimed */
		}
		uiaa.uiaa_iface = ifaces[i];
		uiaa.uiaa_class = ifaces[i]->ui_idesc->bInterfaceClass;
		uiaa.uiaa_subclass = ifaces[i]->ui_idesc->bInterfaceSubClass;
		uiaa.uiaa_proto = ifaces[i]->ui_idesc->bInterfaceProtocol;
		uiaa.uiaa_ifaceno = ifaces[i]->ui_idesc->bInterfaceNumber;

		DPRINTF("searching for interface %d...", i, 0, 0, 0);
		DPRINTF("class %x subclass %x proto %x ifaceno %d",
		    uiaa.uiaa_class, uiaa.uiaa_subclass, uiaa.uiaa_proto,
		    uiaa.uiaa_ifaceno);
		ilocs[USBIFIFCF_INTERFACE] = uiaa.uiaa_ifaceno;
		if (locators != NULL) {
			loc = locators[USBIFIFCF_CONFIGURATION];
			if (loc != USBIFIFCF_CONFIGURATION_DEFAULT &&
			    loc != uiaa.uiaa_configno)
				continue;
			loc = locators[USBIFIFCF_INTERFACE];
			if (loc != USBIFIFCF_INTERFACE_DEFAULT &&
			    loc != uiaa.uiaa_ifaceno)
				continue;
		}
		KERNEL_LOCK(1, NULL);
		dv = config_found_sm_loc(parent, "usbifif", ilocs, &uiaa,
					 usbd_ifprint, config_stdsubmatch);
		KERNEL_UNLOCK_ONE(NULL);
		if (!dv)
			continue;

		usbd_serialnumber(dv, dev);

		/* claim */
		ifaces[i] = NULL;
		/* account for ifaces claimed by the driver behind our back */
		for (j = 0; j < nifaces; j++) {

			if (!ifaces[j] && !dev->ud_subdevs[j]) {
				DPRINTF("interface %d claimed behind our back",
				    j, 0, 0, 0);
				dev->ud_subdevs[j] = dv;
				dev->ud_nifaces_claimed++;
			}
		}
	}

	kmem_free(ifaces, nifaces * sizeof(*ifaces));
	return USBD_NORMAL_COMPLETION;
}
Exemple #25
0
static void
podulebus_probe_podule(struct device *self, int slotnum)
{
	struct podulebus_softc *sc = (struct podulebus_softc *)self;
	bus_space_tag_t id_bst;
	bus_space_handle_t id_bsh;
	int ecid, w;
	u_int8_t extecid[EXTECID_SIZE];
	struct podulebus_attach_args pa;

	bzero(&pa, sizeof(pa));
	id_bst = sc->sc_ioc.ioc_sync_t;
	bus_space_subregion(id_bst, sc->sc_ioc.ioc_sync_h,
			    slotnum * PODULE_GAP, PODULE_GAP, &id_bsh);
	ecid = bus_space_read_1(id_bst, id_bsh, 0);
	/* Skip empty or strange slots */
	if (ecid & (ECID_NOTPRESENT | ECID_NONCONF))
		return;
	if ((ecid & ECID_ID_MASK) == ECID_ID_EXTEND) {
		pa.pa_fast_t = sc->sc_ioc.ioc_fast_t;
		bus_space_subregion(pa.pa_fast_t, sc->sc_ioc.ioc_fast_h,
				    slotnum * PODULE_GAP, PODULE_GAP,
				    &pa.pa_fast_h);
		pa.pa_medium_t = sc->sc_ioc.ioc_medium_t;
		bus_space_subregion(pa.pa_medium_t, sc->sc_ioc.ioc_medium_h,
				    slotnum * PODULE_GAP, PODULE_GAP,
				    &pa.pa_medium_h);
		pa.pa_slow_t = sc->sc_ioc.ioc_slow_t;
		bus_space_subregion(pa.pa_slow_t, sc->sc_ioc.ioc_slow_h,
				    slotnum * PODULE_GAP, PODULE_GAP,
				    &pa.pa_slow_h);
		pa.pa_sync_t = sc->sc_ioc.ioc_sync_t;
		bus_space_subregion(pa.pa_sync_t, sc->sc_ioc.ioc_sync_h,
				    slotnum * PODULE_GAP, PODULE_GAP,
				    &pa.pa_sync_h);
		/* XXX This is a hack! */
		pa.pa_mod_t = &iobus_bs_tag;
		bus_space_map(pa.pa_mod_t,
		    (bus_addr_t)MEMC_IO_BASE + slotnum * (PODULE_GAP << 2),
		    (PODULE_GAP << 2), 0, &pa.pa_mod_h);
		bus_space_read_region_1(id_bst, id_bsh, 0,
					extecid, EXTECID_SIZE);
		/* XXX If you thought that was a hack... */
		pa.pa_mod_base = pa.pa_mod_h;
		pa.pa_fast_base = pa.pa_fast_h;
		pa.pa_medium_base = pa.pa_medium_h;
		pa.pa_slow_base = pa.pa_slow_h;
		pa.pa_sync_base = pa.pa_sync_h;
		pa.pa_ecid = ecid;
		pa.pa_flags1 = extecid[EXTECID_F1];
		pa.pa_manufacturer = (extecid[EXTECID_MLO] |
				      extecid[EXTECID_MHI] << 8);
		pa.pa_product = (extecid[EXTECID_PLO] |
				 extecid[EXTECID_PHI] << 8);
		pa.pa_slotnum = slotnum;
		pa.pa_ih = slotnum;
		if (pa.pa_flags1 & EXTECID_F1_CD) {
			w = pa.pa_flags1 & EXTECID_F1_W_MASK;
			if (w != EXTECID_F1_W_8BIT) {
				/* RISC OS 3 can't handle this either. */
				printf("%s:%d: ROM is not 8 bits wide; "
				    "ignoring it\n",
				    self->dv_xname, pa.pa_slotnum);
			} else {
				podulebus_read_chunks(&pa, 0);
				pa.pa_descr = podulebus_get_chunk(&pa,
							  CHUNK_DEV_DESCR);
			}
		}
		pa.pa_slotflags = 0;
		config_found_sm_loc(self, "podulebus", NULL, &pa,
				podulebus_print, podulebus_submatch);
		if (pa.pa_chunks)
			FREE(pa.pa_chunks, M_DEVBUF);
		if (pa.pa_descr)
			FREE(pa.pa_descr, M_DEVBUF);
		if (pa.pa_loader)
			FREE(pa.pa_loader, M_DEVBUF);
	} else
		printf("%s:%d: non-extended podule ignored.\n",
		       self->dv_xname, slotnum);
}
Exemple #26
0
void 
ubsa_attach(device_t parent, device_t self, void *aux)
{
	struct ubsa_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usb_config_descriptor_t *cdesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	usbd_status err;
	struct ucom_attach_args uca;
	int i;

	sc->sc_dev = self;

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

        sc->sc_udev = dev;
	sc->sc_config_index = UBSA_DEFAULT_CONFIG_INDEX;
	sc->sc_numif = 1; /* default device has one interface */

	/*
	 * initialize rts, dtr variables to something
	 * different from boolean 0, 1
	 */
	sc->sc_dtr = -1;
	sc->sc_rts = -1;

	/*
	 * Quad UMTS cards use different requests to
	 * control com settings and only some.
	 */
	sc->sc_quadumts = 0;
	if (uaa->vendor == USB_VENDOR_OPTIONNV) {
		switch (uaa->product) {
		case USB_PRODUCT_OPTIONNV_QUADUMTS:
		case USB_PRODUCT_OPTIONNV_QUADUMTS2:
			sc->sc_quadumts = 1;
			break;
		}
	}

	DPRINTF(("ubsa attach: sc = %p\n", sc));

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, sc->sc_config_index, 1);
	if (err) {
		aprint_error_dev(self,
		    "failed to set configuration: %s\n",
		    usbd_errstr(err));
		sc->sc_dying = 1;
		goto error;
	}

	/* get the config descriptor */
	cdesc = usbd_get_config_descriptor(sc->sc_udev);

	if (cdesc == NULL) {
		aprint_error_dev(self,
		    "failed to get configuration descriptor\n");
		sc->sc_dying = 1;
		goto error;
	}

	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	/* get the interfaces */
	err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX_OFFSET,
			 &sc->sc_iface[0]);
	if (err) {
		/* can not get main interface */
		sc->sc_dying = 1;
		goto error;
	}

	/* Find the endpoints */
	id = usbd_get_interface_descriptor(sc->sc_iface[0]);
	sc->sc_iface_number[0] = id->bInterfaceNumber;

	/* initialize endpoints */
	uca.bulkin = uca.bulkout = -1;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface[0], i);
		if (ed == NULL) {
			aprint_error_dev(self,
			     "no endpoint descriptor for %d\n", i);
			break;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkin = ed->bEndpointAddress;
			uca.ibufsize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
			uca.obufsize = UGETW(ed->wMaxPacketSize);
		}
	} /* end of Endpoint loop */

	if (sc->sc_intr_number == -1) {
		aprint_error_dev(self, "Could not find interrupt in\n");
		sc->sc_dying = 1;
		goto error;
	}

	if (uca.bulkin == -1) {
		aprint_error_dev(self, "Could not find data bulk in\n");
		sc->sc_dying = 1;
		goto error;
	}

	if (uca.bulkout == -1) {
		aprint_error_dev(self, "Could not find data bulk out\n");
		sc->sc_dying = 1;
		goto error;
	}

	uca.portno = 0;
	/* bulkin, bulkout set above */
	uca.ibufsizepad = uca.ibufsize;
	uca.opkthdrlen = 0;
	uca.device = dev;
	uca.iface = sc->sc_iface[0];
	uca.methods = &ubsa_methods;
	uca.arg = sc;
	uca.info = NULL;
	DPRINTF(("ubsa: int#=%d, in = 0x%x, out = 0x%x, intr = 0x%x\n",
    		i, uca.bulkin, uca.bulkout, sc->sc_intr_number));
	sc->sc_subdevs[0] = config_found_sm_loc(self, "ucombus", NULL, &uca,
				    ucomprint, ucomsubmatch);

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
			   sc->sc_dev);

	return;

error:
	return;
}
Exemple #27
0
static device_t
phantomas_callback(device_t self, struct confargs *ca)
{

	return config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch);
}
Exemple #28
0
static void
bthidev_attach(device_t parent, device_t self, void *aux)
{
	struct bthidev_softc *sc = device_private(self);
	prop_dictionary_t dict = aux;
	prop_object_t obj;
	device_t dev;
	struct bthidev_attach_args bha;
	struct bthidev *hidev;
	struct hid_data *d;
	struct hid_item h;
	const void *desc;
	int locs[BTHIDBUSCF_NLOCS];
	int maxid, rep, dlen;

	/*
	 * Init softc
	 */
	sc->sc_dev = self;
	LIST_INIT(&sc->sc_list);
	callout_init(&sc->sc_reconnect, 0);
	callout_setfunc(&sc->sc_reconnect, bthidev_timeout, sc);
	sc->sc_state = BTHID_CLOSED;
	sc->sc_flags = BTHID_CONNECTING;
	sc->sc_ctlpsm = L2CAP_PSM_HID_CNTL;
	sc->sc_intpsm = L2CAP_PSM_HID_INTR;

	sockopt_init(&sc->sc_mode, BTPROTO_L2CAP, SO_L2CAP_LM, 0);

	/*
	 * extract config from proplist
	 */
	obj = prop_dictionary_get(dict, BTDEVladdr);
	bdaddr_copy(&sc->sc_laddr, prop_data_data_nocopy(obj));

	obj = prop_dictionary_get(dict, BTDEVraddr);
	bdaddr_copy(&sc->sc_raddr, prop_data_data_nocopy(obj));

	obj = prop_dictionary_get(dict, BTDEVmode);
	if (prop_object_type(obj) == PROP_TYPE_STRING) {
		if (prop_string_equals_cstring(obj, BTDEVauth))
			sockopt_setint(&sc->sc_mode, L2CAP_LM_AUTH);
		else if (prop_string_equals_cstring(obj, BTDEVencrypt))
			sockopt_setint(&sc->sc_mode, L2CAP_LM_ENCRYPT);
		else if (prop_string_equals_cstring(obj, BTDEVsecure))
			sockopt_setint(&sc->sc_mode, L2CAP_LM_SECURE);
		else  {
			aprint_error(" unknown %s\n", BTDEVmode);
			return;
		}

		aprint_verbose(" %s %s", BTDEVmode,
					 prop_string_cstring_nocopy(obj));
	}

	obj = prop_dictionary_get(dict, BTHIDEVcontrolpsm);
	if (prop_object_type(obj) == PROP_TYPE_NUMBER) {
		sc->sc_ctlpsm = prop_number_integer_value(obj);
		if (L2CAP_PSM_INVALID(sc->sc_ctlpsm)) {
			aprint_error(" invalid %s\n", BTHIDEVcontrolpsm);
			return;
		}
	}

	obj = prop_dictionary_get(dict, BTHIDEVinterruptpsm);
	if (prop_object_type(obj) == PROP_TYPE_NUMBER) {
		sc->sc_intpsm = prop_number_integer_value(obj);
		if (L2CAP_PSM_INVALID(sc->sc_intpsm)) {
			aprint_error(" invalid %s\n", BTHIDEVinterruptpsm);
			return;
		}
	}

	obj = prop_dictionary_get(dict, BTHIDEVdescriptor);
	if (prop_object_type(obj) == PROP_TYPE_DATA) {
		dlen = prop_data_size(obj);
		desc = prop_data_data_nocopy(obj);
	} else {
		aprint_error(" no %s\n", BTHIDEVdescriptor);
		return;
	}

	obj = prop_dictionary_get(dict, BTHIDEVreconnect);
	if (prop_object_type(obj) == PROP_TYPE_BOOL
	    && !prop_bool_true(obj))
		sc->sc_flags |= BTHID_RECONNECT;

	/*
	 * Parse the descriptor and attach child devices, one per report.
	 */
	maxid = -1;
	h.report_ID = 0;
	d = hid_start_parse(desc, dlen, hid_none);
	while (hid_get_item(d, &h)) {
		if (h.report_ID > maxid)
			maxid = h.report_ID;
	}
	hid_end_parse(d);

	if (maxid < 0) {
		aprint_error(" no reports found\n");
		return;
	}

	aprint_normal("\n");

	for (rep = 0 ; rep <= maxid ; rep++) {
		if (hid_report_size(desc, dlen, hid_feature, rep) == 0
		    && hid_report_size(desc, dlen, hid_input, rep) == 0
		    && hid_report_size(desc, dlen, hid_output, rep) == 0)
			continue;

		bha.ba_desc = desc;
		bha.ba_dlen = dlen;
		bha.ba_input = bthidev_null;
		bha.ba_feature = bthidev_null;
		bha.ba_output = bthidev_output;
		bha.ba_id = rep;

		locs[BTHIDBUSCF_REPORTID] = rep;

		dev = config_found_sm_loc(self, "bthidbus",
					locs, &bha, bthidev_print, config_stdsubmatch);
		if (dev != NULL) {
			hidev = device_private(dev);
			hidev->sc_dev = dev;
			hidev->sc_parent = self;
			hidev->sc_id = rep;
			hidev->sc_input = bha.ba_input;
			hidev->sc_feature = bha.ba_feature;
			LIST_INSERT_HEAD(&sc->sc_list, hidev, sc_next);
		}
	}

	/*
	 * start bluetooth connections
	 */
	mutex_enter(bt_lock);
	if ((sc->sc_flags & BTHID_RECONNECT) == 0)
		bthidev_listen(sc);

	if (sc->sc_flags & BTHID_CONNECTING)
		bthidev_connect(sc);
	mutex_exit(bt_lock);
}
static int
twe_add_unit(struct twe_softc *sc, int unit)
{
	struct twe_param *dtp, *atp;
	struct twe_array_descriptor *ad;
	struct twe_drive *td;
	struct twe_attach_args twea;
	uint32_t newsize;
	int rv;
	uint16_t dsize;
	uint8_t newtype, newstripe;
	int locs[TWECF_NLOCS];

	if (unit < 0 || unit >= TWE_MAX_UNITS)
		return (EINVAL);

	/* Find attached units. */
	rv = twe_param_get(sc, TWE_PARAM_UNITSUMMARY,
	    TWE_PARAM_UNITSUMMARY_Status, TWE_MAX_UNITS, NULL, &dtp);
	if (rv != 0) {
		aprint_error_dev(sc->sc_dev, "error %d fetching unit summary\n",
		    rv);
		return (rv);
	}

	/* For each detected unit, collect size and store in an array. */
	td = &sc->sc_units[unit];

	/* Unit present? */
	if ((dtp->tp_data[unit] & TWE_PARAM_UNITSTATUS_Online) == 0) {
		/*
		 * XXX Should we check to see if a device has been
		 * XXX attached at this index and detach it if it
		 * XXX has?  ("rescan" semantics)
		 */
		rv = 0;
		goto out;
   	}

	rv = twe_param_get_2(sc, TWE_PARAM_UNITINFO + unit,
	    TWE_PARAM_UNITINFO_DescriptorSize, &dsize);
	if (rv != 0) {
		aprint_error_dev(sc->sc_dev, "error %d fetching descriptor size "
		    "for unit %d\n", rv, unit);
		goto out;
	}

	rv = twe_param_get(sc, TWE_PARAM_UNITINFO + unit,
	    TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL, &atp);
	if (rv != 0) {
		aprint_error_dev(sc->sc_dev, "error %d fetching array descriptor "
		    "for unit %d\n", rv, unit);
		goto out;
	}

	ad = (struct twe_array_descriptor *)atp->tp_data;
	newtype = ad->configuration;
	newstripe = ad->stripe_size;
	free(atp, M_DEVBUF);

	rv = twe_param_get_4(sc, TWE_PARAM_UNITINFO + unit,
	    TWE_PARAM_UNITINFO_Capacity, &newsize);
	if (rv != 0) {
		aprint_error_dev(sc->sc_dev,
		    "error %d fetching capacity for unit %d\n",
		    rv, unit);
		goto out;
	}

	/*
	 * Have a device, so we need to attach it.  If there is currently
	 * something sitting at the slot, and the parameters are different,
	 * then we detach the old device before attaching the new one.
	 */
	if (td->td_dev != NULL &&
	    td->td_size == newsize &&
	    td->td_type == newtype &&
	    td->td_stripe == newstripe) {
		/* Same as the old device; just keep using it. */
		rv = 0;
		goto out;
	} else if (td->td_dev != NULL) {
		/* Detach the old device first. */
		(void) config_detach(td->td_dev, DETACH_FORCE);
		td->td_dev = NULL;
	} else if (td->td_size == 0)
		sc->sc_nunits++;

	/*
	 * Committed to the new array unit; assign its parameters and
	 * recompute the number of available command openings.
	 */
	td->td_size = newsize;
	td->td_type = newtype;
	td->td_stripe = newstripe;
	twe_recompute_openings(sc);

	twea.twea_unit = unit;

	locs[TWECF_UNIT] = unit;

	td->td_dev = config_found_sm_loc(sc->sc_dev, "twe", locs, &twea,
					 twe_print, config_stdsubmatch);

	rv = 0;
 out:
	free(dtp, M_DEVBUF);
	return (rv);
}
Exemple #30
0
void
tcattach(struct device *parent, struct device *self, void *aux)
{
	struct tc_softc *sc = device_private(self);
	struct tcbus_attach_args *tba = aux;
	struct tc_attach_args ta;
	const struct tc_builtin *builtin;
	struct tc_slotdesc *slot;
	tc_addr_t tcaddr;
	int i;
	int locs[TCCF_NLOCS];

	printf(": %s MHz clock\n",
	    tba->tba_speed == TC_SPEED_25_MHZ ? "25" : "12.5");

	/*
	 * Save important CPU/chipset information.
	 */
	sc->sc_speed = tba->tba_speed;
	sc->sc_nslots = tba->tba_nslots;
	sc->sc_slots = tba->tba_slots;
	sc->sc_intr_evcnt = tba->tba_intr_evcnt;
	sc->sc_intr_establish = tba->tba_intr_establish;
	sc->sc_intr_disestablish = tba->tba_intr_disestablish;
	sc->sc_get_dma_tag = tba->tba_get_dma_tag;

	/*
	 * Try to configure each built-in device
	 */
	for (i = 0; i < tba->tba_nbuiltins; i++) {
		builtin = &tba->tba_builtins[i];

		/* sanity check! */
		if (builtin->tcb_slot > sc->sc_nslots)
			panic("tcattach: builtin %d slot > nslots", i);

		/*
		 * Make sure device is really there, because some
		 * built-in devices are really optional.
		 */
		tcaddr = sc->sc_slots[builtin->tcb_slot].tcs_addr +
		    builtin->tcb_offset;
		if (tc_badaddr(tcaddr))
			continue;

		/*
		 * Set up the device attachment information.
		 */
		strncpy(ta.ta_modname, builtin->tcb_modname, TC_ROM_LLEN);
		ta.ta_memt = tba->tba_memt;
		ta.ta_dmat = (*sc->sc_get_dma_tag)(builtin->tcb_slot);
		ta.ta_modname[TC_ROM_LLEN] = '\0';
		ta.ta_slot = builtin->tcb_slot;
		ta.ta_offset = builtin->tcb_offset;
		ta.ta_addr = tcaddr;
		ta.ta_cookie = builtin->tcb_cookie;
		ta.ta_busspeed = sc->sc_speed;

		/*
		 * Mark the slot as used, so we don't check it later.
		 */
		sc->sc_slots[builtin->tcb_slot].tcs_used = 1;

		locs[TCCF_SLOT] = builtin->tcb_slot;
		locs[TCCF_OFFSET] = builtin->tcb_offset;
		/*
		 * Attach the device.
		 */
		config_found_sm_loc(self, "tc", locs, &ta,
				    tcprint, config_stdsubmatch);
	}

	/*
	 * Try to configure each unused slot, last to first.
	 */
	for (i = sc->sc_nslots - 1; i >= 0; i--) {
		slot = &sc->sc_slots[i];

		/* If already checked above, don't look again now. */
		if (slot->tcs_used)
			continue;

		/*
		 * Make sure something is there, and find out what it is.
		 */
		tcaddr = slot->tcs_addr;
		if (tc_badaddr(tcaddr))
			continue;
		if (tc_checkslot(tcaddr, ta.ta_modname) == 0)
			continue;

		/*
		 * Set up the rest of the attachment information.
		 */
		ta.ta_memt = tba->tba_memt;
		ta.ta_dmat = (*sc->sc_get_dma_tag)(i);
		ta.ta_slot = i;
		ta.ta_offset = 0;
		ta.ta_addr = tcaddr;
		ta.ta_cookie = slot->tcs_cookie;

		/*
		 * Mark the slot as used.
		 */
		slot->tcs_used = 1;

		locs[TCCF_SLOT] = i;
		locs[TCCF_OFFSET] = 0;
		/*
		 * Attach the device.
		 */
		config_found_sm_loc(self, "tc", locs, &ta,
				    tcprint, config_stdsubmatch);
	}
}