/* * 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); }
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); } }
/* * 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; } }
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"); } } }
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); }
/* * 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); } }
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); }
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; }
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; }
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; }
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); } }
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); }
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; }
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; }
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; }
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); } }
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; }
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++; } }
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); } }
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; }
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); }
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; }
static device_t phantomas_callback(device_t self, struct confargs *ca) { return config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); }
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); }
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); } }