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; }
static void fwohci_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = (struct pci_attach_args *) aux; struct fwohci_pci_softc *psc = device_private(self); char const *intrstr; pci_intr_handle_t ih; uint32_t csr; char intrbuf[PCI_INTRSTR_LEN]; pci_aprint_devinfo(pa, "IEEE 1394 Controller"); fwohci_init(&psc->psc_sc); psc->psc_sc.fc.dev = self; psc->psc_sc.fc.dmat = pa->pa_dmat; psc->psc_pc = pa->pa_pc; psc->psc_tag = pa->pa_tag; /* Map I/O registers */ if (pci_mapreg_map(pa, PCI_OHCI_MAP_REGISTER, PCI_MAPREG_TYPE_MEM, 0, &psc->psc_sc.bst, &psc->psc_sc.bsh, NULL, &psc->psc_sc.bssize)) { aprint_error_dev(self, "can't map OHCI register space\n"); goto fail; } /* Disable interrupts, so we don't get any spurious ones. */ OWRITE(&psc->psc_sc, FWOHCI_INTMASKCLR, OHCI_INT_EN); /* Enable the device. */ csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); csr |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr); /* * Some Sun FireWire controllers have their intpin register * bogusly set to 0, although it should be 3. Correct that. */ if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN) && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_FIREWIRE)) if (pa->pa_intrpin == 0) pa->pa_intrpin = 3; /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); goto fail; } intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); psc->psc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, fwohci_intr, &psc->psc_sc); if (psc->psc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); goto fail; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); if (fwohci_attach(&psc->psc_sc) != 0) goto fail; if (!pmf_device_register(self, fwohci_pci_suspend, fwohci_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); return; fail: /* In the event that we fail to attach, register a null pnp handler */ if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); return; }
static void coram_attach(device_t parent, device_t self, void *aux) { struct coram_softc *sc = device_private(self); const struct pci_attach_args *pa = aux; pci_intr_handle_t ih; pcireg_t reg; const char *intrstr; struct coram_iic_softc *cic; uint32_t value; int i; #ifdef CORAM_ATTACH_I2C struct i2cbus_attach_args iba; #endif sc->sc_dev = self; pci_aprint_devinfo(pa, NULL); reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); sc->sc_board = coram_board_lookup(PCI_VENDOR(reg), PCI_PRODUCT(reg)); KASSERT(sc->sc_board != NULL); if (pci_mapreg_map(pa, CX23885_MMBASE, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) { aprint_error_dev(self, "couldn't map memory space\n"); return; } sc->sc_dmat = pa->pa_dmat; sc->sc_pc = pa->pa_pc; if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_VM, coram_intr, self); if (sc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* set master */ reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); reg |= PCI_COMMAND_MASTER_ENABLE; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg); /* I2C */ for(i = 0; i < I2C_NUM; i++) { cic = &sc->sc_iic[i]; cic->cic_sc = sc; if (bus_space_subregion(sc->sc_memt, sc->sc_memh, I2C_BASE + (I2C_SIZE * i), I2C_SIZE, &cic->cic_regh)) panic("failed to subregion i2c"); mutex_init(&cic->cic_busmutex, MUTEX_DRIVER, IPL_NONE); cic->cic_i2c.ic_cookie = cic; cic->cic_i2c.ic_acquire_bus = coram_iic_acquire_bus; cic->cic_i2c.ic_release_bus = coram_iic_release_bus; cic->cic_i2c.ic_exec = coram_iic_exec; #ifdef CORAM_ATTACH_I2C /* attach iic(4) */ memset(&iba, 0, sizeof(iba)); iba.iba_tag = &cic->cic_i2c; iba.iba_type = I2C_TYPE_SMBUS; cic->cic_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print); #endif } /* HVR1250 GPIO */ value = bus_space_read_4(sc->sc_memt, sc->sc_memh, 0x110010); #if 1 value &= ~0x00010001; bus_space_write_4(sc->sc_memt, sc->sc_memh, 0x110010, value); delay(5000); #endif value |= 0x00010001; bus_space_write_4(sc->sc_memt, sc->sc_memh, 0x110010, value); #if 0 int i; uint8_t foo[256]; uint8_t bar; bar = 0; // seeprom_bootstrap_read(&sc->sc_i2c, 0x50, 0, 256, foo, 256); iic_acquire_bus(&sc->sc_i2c, I2C_F_POLL); iic_exec(&sc->sc_i2c, I2C_OP_READ_WITH_STOP, 0x50, &bar, 1, foo, 256, I2C_F_POLL); iic_release_bus(&sc->sc_i2c, I2C_F_POLL); printf("\n"); for ( i = 0; i < 256; i++) { if ( (i % 8) == 0 ) printf("%02x: ", i); printf("%02x", foo[i]); if ( (i % 8) == 7 ) printf("\n"); else printf(" "); } printf("\n"); #endif sc->sc_demod = cx24227_open(sc->sc_dev, &sc->sc_iic[0].cic_i2c, 0x19); if (sc->sc_demod == NULL) aprint_error_dev(self, "couldn't open cx24227\n"); sc->sc_tuner = mt2131_open(sc->sc_dev, &sc->sc_iic[0].cic_i2c, 0x61); if (sc->sc_tuner == NULL) aprint_error_dev(self, "couldn't open mt2131\n"); coram_mpeg_attach(sc); if (!pmf_device_register(self, NULL, coram_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); return; }
/* * Attach hardware to driver, attach hardware driver to audio * pseudo-device driver. */ void wss_isapnp_attach(device_t parent, device_t self, void *aux) { struct wss_softc *sc; struct ad1848_softc *ac; struct isapnp_attach_args *ipa; int variant; sc = device_private(self); ac = &sc->sc_ad1848.sc_ad1848; ac->sc_dev = self; ipa = aux; printf("\n"); if (!isapnp_devmatch(aux, &isapnp_wss_devinfo, &variant)) { aprint_error_dev(self, "match failed?\n"); return; } if (isapnp_config(ipa->ipa_iot, ipa->ipa_memt, ipa)) { aprint_error_dev(self, "error in region allocation\n"); return; } switch (variant) { case 1: /* We have to put the chip into `WSS mode'. */ { bus_space_tag_t iot; bus_space_handle_t ioh; iot = ipa->ipa_iot; ioh = ipa->ipa_io[0].h; while (bus_space_read_1(iot, ioh, SBP_DSP_WSTAT) & SB_DSP_BUSY); bus_space_write_1(iot, ioh, SBP_DSP_WRITE, 0x09); while (bus_space_read_1(iot, ioh, SBP_DSP_WSTAT) & SB_DSP_BUSY); bus_space_write_1(iot, ioh, SBP_DSP_WRITE, 0x00); while (bus_space_read_1(iot, ioh, SBP_DSP_WSTAT) & SB_DSP_BUSY); delay(1000); } sc->sc_iot = ipa->ipa_iot; sc->sc_ioh = ipa->ipa_io[2].h; break; default: sc->sc_iot = ipa->ipa_iot; sc->sc_ioh = ipa->ipa_io[0].h; break; } sc->mad_chip_type = MAD_NONE; /* Set up AD1848 I/O handle. */ ac->sc_iot = sc->sc_iot; ac->sc_ioh = sc->sc_ioh; sc->sc_ad1848.sc_ic = ipa->ipa_ic; sc->wss_ic = ipa->ipa_ic; sc->wss_irq = ipa->ipa_irq[0].num; sc->wss_playdrq = ipa->ipa_drq[0].num; sc->wss_recdrq = ipa->ipa_ndrq > 1 ? ipa->ipa_drq[1].num : ipa->ipa_drq[0].num; if (!ad1848_isa_probe(&sc->sc_ad1848)) { aprint_error_dev(self, "ad1848_probe failed\n"); return; } aprint_error_dev(self, "%s %s", ipa->ipa_devident, ipa->ipa_devclass); ac->mode = 2; wssattach(sc); /* set up OPL I/O handle for ISAPNP boards w/o MAD */ if (ipa->ipa_nio > 1 && sc->mad_chip_type == MAD_NONE) { struct audio_attach_args arg; sc->sc_opl_ioh = ipa->ipa_io[1].h; arg.type = AUDIODEV_TYPE_OPL; arg.hwif = 0; arg.hdl = 0; (void)config_found(self, &arg, audioprint); } }
/* * Attach a display. We need to notice if it is the console, too. */ static void p9100_sbus_attach(struct device *parent, struct device *self, void *args) { struct p9100_softc *sc = device_private(self); struct sbus_attach_args *sa = args; struct fbdevice *fb = &sc->sc_fb; int isconsole; int node; int i, j; uint8_t ver; #if NWSDISPLAY > 0 struct wsemuldisplaydev_attach_args aa; struct rasops_info *ri; unsigned long defattr; #endif sc->sc_last_offset = 0xffffffff; /* Remember cookies for p9100_mmap() */ sc->sc_bustag = sa->sa_bustag; sc->sc_ctl_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base); sc->sc_ctl_psize = 0x8000;/*(bus_size_t)sa->sa_reg[0].oa_size;*/ sc->sc_cmd_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_reg[1].oa_space, sa->sa_reg[1].oa_base); sc->sc_cmd_psize = (bus_size_t)sa->sa_reg[1].oa_size; sc->sc_fb_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_reg[2].oa_space, sa->sa_reg[2].oa_base); sc->sc_fb_psize = (bus_size_t)sa->sa_reg[2].oa_size; fb->fb_driver = &p9100fbdriver; fb->fb_device = &sc->sc_dev; fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK; #ifdef PNOZZ_EMUL_CG3 fb->fb_type.fb_type = FBTYPE_SUN3COLOR; #else fb->fb_type.fb_type = FBTYPE_P9100; #endif fb->fb_pixels = NULL; sc->sc_mode = WSDISPLAYIO_MODE_EMUL; node = sa->sa_node; isconsole = fb_is_console(node); if (!isconsole) { aprint_normal("\n"); aprint_error_dev(self, "fatal error: PROM didn't configure device\n"); return; } /* * When the ROM has mapped in a p9100 display, the address * maps only the video RAM, so in any case we have to map the * registers ourselves. We only need the video RAM if we are * going to print characters via rconsole. */ if (sbus_bus_map(sc->sc_bustag, sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base, /* * XXX for some reason the SBus resources don't cover * all registers, so we just map what we need */ /*sc->sc_ctl_psize*/ 0x8000, /*BUS_SPACE_MAP_LINEAR*/0, &sc->sc_ctl_memh) != 0) { aprint_error_dev(self, "cannot map control registers\n"); return; } if (sa->sa_npromvaddrs != 0) fb->fb_pixels = (void *)sa->sa_promvaddrs[0]; if (fb->fb_pixels == NULL) { if (sbus_bus_map(sc->sc_bustag, sa->sa_reg[2].oa_space, sa->sa_reg[2].oa_base, sc->sc_fb_psize, BUS_SPACE_MAP_LINEAR, &sc->sc_fb_memh) != 0) { aprint_error_dev(self, "cannot map framebuffer\n"); return; } fb->fb_pixels = (char *)sc->sc_fb_memh; } else { sc->sc_fb_memh = (bus_space_handle_t) fb->fb_pixels; } i = p9100_ctl_read_4(sc, 0x0004); switch ((i >> 26) & 7) { case 5: fb->fb_type.fb_depth = 32; break; case 7: fb->fb_type.fb_depth = 24; break; case 3: fb->fb_type.fb_depth = 16; break; case 2: fb->fb_type.fb_depth = 8; break; default: { panic("pnozz: can't determine screen depth (0x%02x)", i); } } sc->sc_depth = (fb->fb_type.fb_depth >> 3); /* XXX for some reason I get a kernel trap with this */ sc->sc_width = prom_getpropint(node, "width", 800); sc->sc_height = prom_getpropint(node, "height", 600); sc->sc_stride = prom_getpropint(node, "linebytes", sc->sc_width * (fb->fb_type.fb_depth >> 3)); /* check the RAMDAC */ ver = p9100_ramdac_read_ctl(sc, DAC_VERSION); p9100_init_engine(sc); fb_setsize_obp(fb, fb->fb_type.fb_depth, sc->sc_width, sc->sc_height, node); sbus_establish(&sc->sc_sd, &sc->sc_dev); bus_intr_establish(sc->sc_bustag, sa->sa_pri, IPL_BIO, p9100_intr, sc); fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; printf(": rev %d / %x, %dx%d, depth %d mem %x", (i & 7), ver, fb->fb_type.fb_width, fb->fb_type.fb_height, fb->fb_type.fb_depth, (unsigned int)sc->sc_fb_psize); fb->fb_type.fb_cmsize = prom_getpropint(node, "cmsize", 256); if ((1 << fb->fb_type.fb_depth) != fb->fb_type.fb_cmsize) printf(", %d entry colormap", fb->fb_type.fb_cmsize); /* Initialize the default color map. */ /*bt_initcmap(&sc->sc_cmap, 256);*/ j = 0; for (i = 0; i < 256; i++) { sc->sc_cmap.cm_map[i][0] = rasops_cmap[j]; j++; sc->sc_cmap.cm_map[i][1] = rasops_cmap[j]; j++; sc->sc_cmap.cm_map[i][2] = rasops_cmap[j]; j++; } p9100loadcmap(sc, 0, 256); /* make sure we are not blanked */ if (isconsole) p9100_set_video(sc, 1); if (shutdownhook_establish(p9100_shutdown, sc) == NULL) { panic("%s: could not establish shutdown hook", device_xname(&sc->sc_dev)); } if (isconsole) { printf(" (console)\n"); #ifdef RASTERCONSOLE /*p9100loadcmap(sc, 255, 1);*/ fbrcons_init(fb); #endif } else printf("\n"); #if NWSDISPLAY > 0 wsfont_init(); vcons_init(&sc->vd, sc, &p9100_defscreendesc, &p9100_accessops); sc->vd.init_screen = p9100_init_screen; vcons_init_screen(&sc->vd, &p9100_console_screen, 1, &defattr); p9100_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; sc->sc_bg = (defattr >> 16) & 0xff; p9100_clearscreen(sc); ri = &p9100_console_screen.scr_ri; p9100_defscreendesc.nrows = ri->ri_rows; p9100_defscreendesc.ncols = ri->ri_cols; p9100_defscreendesc.textops = &ri->ri_ops; p9100_defscreendesc.capabilities = ri->ri_caps; if(isconsole) { wsdisplay_cnattach(&p9100_defscreendesc, ri, 0, 0, defattr); } aa.console = isconsole; aa.scrdata = &p9100_screenlist; aa.accessops = &p9100_accessops; aa.accesscookie = &sc->vd; config_found(self, &aa, wsemuldisplaydevprint); #endif /* cursor sprite handling */ p9100_init_cursor(sc); /* attach the fb */ fb_attach(fb, isconsole); /* register with power management */ sc->sc_video = 1; sc->sc_powerstate = PWR_RESUME; powerhook_establish(device_xname(&sc->sc_dev), p9100_power_hook, sc); #if NTCTRL > 0 /* register callback for external monitor status change */ tadpole_register_callback(p9100_set_extvga, sc); #endif }
static void pwmclock_attach(device_t parent, device_t self, void *aux) { struct pwmclock_softc *sc = device_private(self); struct voyager_attach_args *vaa = aux; const struct sysctlnode *sysctl_node, *me, *freq; uint32_t reg, last, curr, diff, acc; int i, clk; sc->sc_dev = self; sc->sc_memt = vaa->vaa_tag; sc->sc_regh = vaa->vaa_regh; aprint_normal("\n"); /* NULL here gets us the clockframe */ voyager_establish_intr(parent, 22, pwmclock_intr, NULL); reg = voyager_set_pwm(100, 100); /* 100Hz, 10% duty cycle */ reg |= SM502_PWM_ENABLE | SM502_PWM_ENABLE_INTR | SM502_PWM_INTR_PENDING; sc->sc_reg = reg; pwmclock = sc; initclocks_ptr = pwmclock_start; /* * Establish a hook so on shutdown we can set the CPU clock back to * full speed. This is necessary because PMON doesn't change the * clock scale register on a warm boot, the MIPS clock code gets * confused if we're too slow and the loongson-specific bits run * too late in the boot process */ sc->sc_shutdown_cookie = shutdownhook_establish(pwmclock_shutdown, sc); /* ok, let's see how far the cycle counter gets between interrupts */ DPRINTF("calibrating CPU timer...\n"); for (clk = 1; clk < 8; clk++) { REGVAL(LS2F_CHIPCFG0) = (REGVAL(LS2F_CHIPCFG0) & ~LS2FCFG_FREQSCALE_MASK) | clk; bus_space_write_4(sc->sc_memt, sc->sc_regh, SM502_PWM1, sc->sc_reg); acc = 0; last = pwmclock_wait_edge(sc); for (i = 0; i < 16; i++) { curr = pwmclock_wait_edge(sc); diff = curr - last; acc += diff; last = curr; } sc->sc_scale[clk] = (acc >> 4) / 5000; } #ifdef PWMCLOCK_DEBUG for (clk = 1; clk < 8; clk++) { aprint_normal_dev(sc->sc_dev, "%d/8: %d\n", clk + 1, sc->sc_scale[clk]); } #endif sc->sc_step = 7; sc->sc_step_wanted = 7; /* now setup sysctl */ if (sysctl_createv(NULL, 0, NULL, &me, CTLFLAG_READWRITE, CTLTYPE_NODE, "loongson", NULL, NULL, 0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL) != 0) aprint_error_dev(sc->sc_dev, "couldn't create 'loongson' node\n"); if (sysctl_createv(NULL, 0, NULL, &freq, CTLFLAG_READWRITE, CTLTYPE_NODE, "frequency", NULL, NULL, 0, NULL, 0, CTL_MACHDEP, me->sysctl_num, CTL_CREATE, CTL_EOL) != 0) aprint_error_dev(sc->sc_dev, "couldn't create 'frequency' node\n"); if (sysctl_createv(NULL, 0, NULL, &sysctl_node, CTLFLAG_READWRITE | CTLFLAG_OWNDESC, CTLTYPE_INT, "target", "CPU speed", pwmclock_cpuspeed_temp, 0, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num, CTL_CREATE, CTL_EOL) == 0) { } else aprint_error_dev(sc->sc_dev, "couldn't create 'target' node\n"); if (sysctl_createv(NULL, 0, NULL, &sysctl_node, CTLFLAG_READWRITE, CTLTYPE_INT, "current", NULL, pwmclock_cpuspeed_cur, 1, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num, CTL_CREATE, CTL_EOL) == 0) { } else aprint_error_dev(sc->sc_dev, "couldn't create 'current' node\n"); if (sysctl_createv(NULL, 0, NULL, &sysctl_node, CTLFLAG_READWRITE, CTLTYPE_STRING, "available", NULL, pwmclock_cpuspeed_available, 2, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num, CTL_CREATE, CTL_EOL) == 0) { } else aprint_error_dev(sc->sc_dev, "couldn't create 'available' node\n"); }
static void ecadc_attach(device_t parent, device_t self, void *aux) { struct i2c_attach_args *ia = aux; struct ecadc_softc *sc = device_private(self); u_char term[256]; u_char *cp, *desc; int64_t minv, warnv, crit, num, den; u_int8_t junk[PCF8591_CHANNELS + 1]; envsys_data_t *sensor; int len, error, addr, chan, node = (int)ia->ia_cookie; u_int i; sc->sc_dev = self; if ((len = OF_getprop(node, "thermisters", term, sizeof(term))) < 0) { aprint_error(": couldn't find \"thermisters\" property\n"); return; } if (OF_getprop(node, "cpu-temp-factors", &sc->sc_cpu_xlate[2], sizeof(sc->sc_cpu_xlate) - 2) < 0) { aprint_error(": couldn't find \"cpu-temp-factors\" property\n"); return; } sc->sc_cpu_xlate[0] = sc->sc_cpu_xlate[1] = sc->sc_cpu_xlate[2]; /* Only the Sun Enterprise 450 has these. */ OF_getprop(node, "ps-temp-factors", &sc->sc_ps_xlate[2], sizeof(sc->sc_ps_xlate) - 2); sc->sc_ps_xlate[0] = sc->sc_ps_xlate[1] = sc->sc_ps_xlate[2]; cp = term; while (cp < term + len) { addr = cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3]; cp += 4; chan = cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3]; cp += 4; minv = cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3]; cp += 4; warnv = cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3]; cp += 4; crit = cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3]; cp += 4; num = cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3]; cp += 4; den = cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3]; cp += 4; desc = cp; while (cp < term + len && *cp++); if (addr != (ia->ia_addr << 1)) continue; if (num == 0 || den == 0) num = den = 1; sc->sc_channels[sc->sc_nchan].chan_num = chan; sensor = &sc->sc_channels[sc->sc_nchan].chan_sensor; sensor->units = ENVSYS_STEMP; sensor->flags |= ENVSYS_FMONLIMITS; sensor->state = ENVSYS_SINVALID; strlcpy(sensor->desc, desc, sizeof(sensor->desc)); if (strncmp(desc, "CPU", 3) == 0) sc->sc_channels[sc->sc_nchan].chan_xlate = sc->sc_cpu_xlate; else if (strncmp(desc, "PS", 2) == 0) sc->sc_channels[sc->sc_nchan].chan_xlate = sc->sc_ps_xlate; else sc->sc_channels[sc->sc_nchan].chan_factor = (1000000 * num) / den; sc->sc_channels[sc->sc_nchan].chan_min = 273150000 + 1000000 * minv; sc->sc_channels[sc->sc_nchan].chan_warn = 273150000 + 1000000 * warnv; sc->sc_channels[sc->sc_nchan].chan_crit = 273150000 + 1000000 * crit; sc->sc_nchan++; } sc->sc_tag = ia->ia_tag; sc->sc_addr = ia->ia_addr; iic_acquire_bus(sc->sc_tag, 0); /* Try a read now, so we can fail if it doesn't work */ if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, NULL, 0, junk, sc->sc_nchan + 1, 0)) { aprint_error(": read failed\n"); iic_release_bus(sc->sc_tag, 0); return; } iic_release_bus(sc->sc_tag, 0); /* Hook us into the sysmon_envsys subsystem */ sc->sc_sme = sysmon_envsys_create(); sc->sc_sme->sme_name = device_xname(self); sc->sc_sme->sme_cookie = sc; sc->sc_sme->sme_refresh = ecadc_refresh; sc->sc_sme->sme_get_limits = ecadc_get_limits; /* Initialize sensor data. */ for (i = 0; i < sc->sc_nchan; i++) sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_channels[i].chan_sensor); error = sysmon_envsys_register(sc->sc_sme); if (error) { aprint_error_dev(self, "error %d registering with sysmon\n", error); sysmon_envsys_destroy(sc->sc_sme); return; } aprint_naive(": Temp Sensors\n"); aprint_normal(": %s Temp Sensors\n", ia->ia_name); }
static int ld_virtio_alloc_reqs(struct ld_virtio_softc *sc, int qsize) { int allocsize, r, rsegs, i; struct ld_softc *ld = &sc->sc_ld; void *vaddr; allocsize = sizeof(struct virtio_blk_req) * qsize; r = bus_dmamem_alloc(sc->sc_virtio->sc_dmat, allocsize, 0, 0, &sc->sc_reqs_segs[0], 1, &rsegs, BUS_DMA_NOWAIT); if (r != 0) { aprint_error_dev(sc->sc_dev, "DMA memory allocation failed, size %d, " "error code %d\n", allocsize, r); goto err_none; } r = bus_dmamem_map(sc->sc_virtio->sc_dmat, &sc->sc_reqs_segs[0], 1, allocsize, &vaddr, BUS_DMA_NOWAIT); if (r != 0) { aprint_error_dev(sc->sc_dev, "DMA memory map failed, " "error code %d\n", r); goto err_dmamem_alloc; } sc->sc_reqs = vaddr; memset(vaddr, 0, allocsize); for (i = 0; i < qsize; i++) { struct virtio_blk_req *vr = &sc->sc_reqs[i]; r = bus_dmamap_create(sc->sc_virtio->sc_dmat, offsetof(struct virtio_blk_req, vr_bp), 1, offsetof(struct virtio_blk_req, vr_bp), 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &vr->vr_cmdsts); if (r != 0) { aprint_error_dev(sc->sc_dev, "command dmamap creation failed, " "error code %d\n", r); goto err_reqs; } r = bus_dmamap_load(sc->sc_virtio->sc_dmat, vr->vr_cmdsts, &vr->vr_hdr, offsetof(struct virtio_blk_req, vr_bp), NULL, BUS_DMA_NOWAIT); if (r != 0) { aprint_error_dev(sc->sc_dev, "command dmamap load failed, " "error code %d\n", r); goto err_reqs; } r = bus_dmamap_create(sc->sc_virtio->sc_dmat, ld->sc_maxxfer, ld->sc_maxxfer / NBPG, ld->sc_maxxfer, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &vr->vr_payload); if (r != 0) { aprint_error_dev(sc->sc_dev, "payload dmamap creation failed, " "error code %d\n", r); goto err_reqs; } } return 0; err_reqs: for (i = 0; i < qsize; i++) { struct virtio_blk_req *vr = &sc->sc_reqs[i]; if (vr->vr_cmdsts) { bus_dmamap_destroy(sc->sc_virtio->sc_dmat, vr->vr_cmdsts); vr->vr_cmdsts = 0; } if (vr->vr_payload) { bus_dmamap_destroy(sc->sc_virtio->sc_dmat, vr->vr_payload); vr->vr_payload = 0; } } bus_dmamem_unmap(sc->sc_virtio->sc_dmat, sc->sc_reqs, allocsize); err_dmamem_alloc: bus_dmamem_free(sc->sc_virtio->sc_dmat, &sc->sc_reqs_segs[0], 1); err_none: return -1; }
void pcic_pci_attach(device_t parent, device_t self, void *aux) { struct pcic_pci_softc *psc = device_private(self); struct pcic_softc *sc = &psc->sc_pcic; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; bus_space_tag_t memt = pa->pa_memt; bus_space_handle_t memh; const char *model; sc->dev = self; aprint_naive(": PCMCIA controller\n"); if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &sc->iot, &sc->ioh, NULL, NULL)) { aprint_error(": can't map i/o space\n"); return; } /* * XXX need some memory for mapping pcmcia cards into. Ideally, this * would be completely dynamic. Practically this doesn't work, * because the extent mapper doesn't know about all the devices all * the time. With ISA we could finesse the issue by specifying the * memory region in the config line. We can't do that here, so we * cheat for now. Jason Thorpe, you are my Savior, come up with a fix * :-) */ /* Map mem space. */ if (bus_space_map(memt, 0xd0000, 0x4000, 0, &memh)) panic("pcic_pci_attach: can't map mem space"); sc->membase = 0xd0000; sc->subregionmask = (1 << (0x4000 / PCIC_MEM_PAGESIZE)) - 1; /* same deal for io allocation */ sc->iobase = 0x400; sc->iosize = 0xbff; /* end XXX */ sc->pct = &pcic_pci_functions; sc->memt = memt; sc->memh = memh; switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_CIRRUS_CL_PD6729: model = "Cirrus Logic PD6729 PCMCIA controller"; break; default: model = "Model unknown"; break; } aprint_normal(": %s\n", model); /* Enable the card. */ pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) | PCI_COMMAND_MASTER_ENABLE); pcic_attach(sc); /* * Check to see if we're using PCI or ISA interrupts. I don't * know of any i386 systems that use the 6729 in PCI interrupt * mode, but maybe when the PCMCIA code runs on other platforms * we'll need to fix this. */ pcic_write(&sc->handle[0], PCIC_CIRRUS_EXTENDED_INDEX, PCIC_CIRRUS_EXT_CONTROL_1); if ((pcic_read(&sc->handle[0], PCIC_CIRRUS_EXTENDED_DATA) & PCIC_CIRRUS_EXT_CONTROL_1_PCI_INTR_MASK)) { aprint_error_dev(self, "PCI interrupts not supported\n"); return; } psc->intr_est = pcic_pci_machdep_intr_est(pc); sc->irq = -1; #if 0 /* Map and establish the interrupt. */ sc->ih = pcic_pci_machdep_pcic_intr_establish(sc, pcic_intr); if (sc->ih == NULL) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } #endif /* * Defer configuration of children until ISA has had its chance * to use up whatever IO space and IRQs it wants. XXX This will * only work if ISA is attached to a pcib, AND the PCI probe finds * and defers the ISA attachment before this one. */ config_defer(self, pcic_pci_callback); config_interrupts(self, pcic_isa_config_interrupts); }
static void aps_attach(device_t parent, device_t self, void *aux) { struct aps_softc *sc = device_private(self); struct isa_attach_args *ia = aux; int iobase, i; sc->sc_iot = ia->ia_iot; iobase = ia->ia_io[0].ir_addr; if (bus_space_map(sc->sc_iot, iobase, APS_ADDR_SIZE, 0, &sc->sc_ioh)) { aprint_error(": can't map i/o space\n"); return; } aprint_naive("\n"); aprint_normal("\n"); if (!aps_init(sc)) { aprint_error_dev(self, "failed to initialise\n"); goto out; } /* Initialize sensors */ #define INITDATA(idx, unit, string) \ sc->sc_sensor[idx].units = unit; \ strlcpy(sc->sc_sensor[idx].desc, string, \ sizeof(sc->sc_sensor[idx].desc)); INITDATA(APS_SENSOR_XACCEL, ENVSYS_INTEGER, "X_ACCEL"); INITDATA(APS_SENSOR_YACCEL, ENVSYS_INTEGER, "Y_ACCEL"); INITDATA(APS_SENSOR_TEMP1, ENVSYS_STEMP, "TEMP_1"); INITDATA(APS_SENSOR_TEMP2, ENVSYS_STEMP, "TEMP_2"); INITDATA(APS_SENSOR_XVAR, ENVSYS_INTEGER, "X_VAR"); INITDATA(APS_SENSOR_YVAR, ENVSYS_INTEGER, "Y_VAR"); INITDATA(APS_SENSOR_KBACT, ENVSYS_INDICATOR, "Keyboard Active"); INITDATA(APS_SENSOR_MSACT, ENVSYS_INDICATOR, "Mouse Active"); INITDATA(APS_SENSOR_LIDOPEN, ENVSYS_INDICATOR, "Lid Open"); sc->sc_sme = sysmon_envsys_create(); for (i = 0; i < APS_NUM_SENSORS; i++) { sc->sc_sensor[i].state = ENVSYS_SVALID; if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i])) { sysmon_envsys_destroy(sc->sc_sme); goto out; } } /* * Register with the sysmon_envsys(9) framework. */ sc->sc_sme->sme_name = device_xname(self); sc->sc_sme->sme_flags = SME_DISABLE_REFRESH; if ((i = sysmon_envsys_register(sc->sc_sme))) { aprint_error_dev(self, "unable to register with sysmon (%d)\n", i); sysmon_envsys_destroy(sc->sc_sme); goto out; } if (!pmf_device_register(self, aps_suspend, aps_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Refresh sensor data every 0.5 seconds */ callout_init(&sc->sc_callout, 0); callout_setfunc(&sc->sc_callout, aps_refresh, sc); callout_schedule(&sc->sc_callout, (hz) / 2); aprint_normal_dev(self, "Thinkpad Active Protection System\n"); return; out: bus_space_unmap(sc->sc_iot, sc->sc_ioh, APS_ADDR_SIZE); }
/* ARGSUSED */ static void bcmemmc_attach(device_t parent, device_t self, void *aux) { struct bcmemmc_softc *sc = device_private(self); prop_dictionary_t dict = device_properties(self); struct amba_attach_args *aaa = aux; prop_number_t frequency; int error; sc->sc.sc_dev = self; sc->sc.sc_dmat = aaa->aaa_dmat; sc->sc.sc_flags = 0; sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS; sc->sc.sc_flags |= SDHC_FLAG_HOSTCAPS; sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT; sc->sc.sc_caps = SDHC_VOLTAGE_SUPP_3_3V | SDHC_HIGH_SPEED_SUPP | (SDHC_MAX_BLK_LEN_1024 << SDHC_MAX_BLK_LEN_SHIFT); sc->sc.sc_caps2 = SDHC_SDR50_SUPP; sc->sc.sc_host = sc->sc_hosts; sc->sc.sc_clkbase = 50000; /* Default to 50MHz */ sc->sc_iot = aaa->aaa_iot; /* Fetch the EMMC clock frequency from property if set. */ frequency = prop_dictionary_get(dict, "frequency"); if (frequency != NULL) { sc->sc.sc_clkbase = prop_number_integer_value(frequency) / 1000; } error = bus_space_map(sc->sc_iot, aaa->aaa_addr, aaa->aaa_size, 0, &sc->sc_ioh); if (error) { aprint_error_dev(self, "can't map registers for %s: %d\n", aaa->aaa_name, error); return; } sc->sc_ios = aaa->aaa_size; sc->sc_physaddr = aaa->aaa_addr; aprint_naive(": SDHC controller\n"); aprint_normal(": SDHC controller\n"); sc->sc_ih = intr_establish(aaa->aaa_intr, IPL_SDMMC, IST_LEVEL, sdhc_intr, &sc->sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "failed to establish interrupt %d\n", aaa->aaa_intr); goto fail; } aprint_normal_dev(self, "interrupting on intr %d\n", aaa->aaa_intr); #if NBCMDMAC > 0 sc->sc_dmac = bcm_dmac_alloc(BCM_DMAC_TYPE_NORMAL, IPL_SDMMC, bcmemmc_dma_done, sc); if (sc->sc_dmac == NULL) goto done; sc->sc.sc_flags |= SDHC_FLAG_USE_DMA; sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA; sc->sc.sc_caps |= SDHC_DMA_SUPPORT; sc->sc.sc_vendor_transfer_data_dma = bcmemmc_xfer_data_dma; sc->sc_state = EMMC_DMA_STATE_IDLE; cv_init(&sc->sc_cv, "bcmemmcdma"); int rseg; error = bus_dmamem_alloc(sc->sc.sc_dmat, PAGE_SIZE, PAGE_SIZE, PAGE_SIZE, sc->sc_segs, 1, &rseg, BUS_DMA_WAITOK); if (error) { aprint_error_dev(self, "dmamem_alloc failed (%d)\n", error); goto fail; } error = bus_dmamem_map(sc->sc.sc_dmat, sc->sc_segs, rseg, PAGE_SIZE, (void **)&sc->sc_cblk, BUS_DMA_WAITOK); if (error) { aprint_error_dev(self, "dmamem_map failed (%d)\n", error); goto fail; } KASSERT(sc->sc_cblk != NULL); memset(sc->sc_cblk, 0, PAGE_SIZE); error = bus_dmamap_create(sc->sc.sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0, BUS_DMA_WAITOK, &sc->sc_dmamap); if (error) { aprint_error_dev(self, "dmamap_create failed (%d)\n", error); goto fail; } error = bus_dmamap_load(sc->sc.sc_dmat, sc->sc_dmamap, sc->sc_cblk, PAGE_SIZE, NULL, BUS_DMA_WAITOK|BUS_DMA_WRITE); if (error) { aprint_error_dev(self, "dmamap_load failed (%d)\n", error); goto fail; } done: #endif config_interrupts(self, bcmemmc_attach_i); return; fail: /* XXX add bus_dma failure cleanup */ if (sc->sc_ih) { intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; } bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); }
/* * Attach all the sub-devices we can find */ static void bha_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct bha_softc *sc = device_private(self); bus_space_tag_t iot; bus_space_handle_t ioh; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; pcireg_t csr; const char *model, *intrstr; sc->sc_dev = self; aprint_naive(": SCSI controller\n"); if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BUSLOGIC_MULTIMASTER_NC) model = "BusLogic 9xxC SCSI"; else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BUSLOGIC_MULTIMASTER) model = "BusLogic 9xxC SCSI"; else model = "unknown model!"; aprint_normal(": %s\n", model); if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL)) { aprint_error_dev(sc->sc_dev, "unable to map device registers\n"); return; } sc->sc_iot = iot; sc->sc_ioh = ioh; sc->sc_dmat = pa->pa_dmat; if (!bha_find(iot, ioh)) panic("bha_pci_attach: bha_find failed"); sc->sc_dmaflags = 0; csr = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_IO_ENABLE); if (pci_intr_map(pa, &ih)) { aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, bha_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(sc->sc_dev, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); bha_attach(sc); bha_disable_isacompat(sc); }
static void pq3ehci_attach(device_t parent, device_t self, void *aux) { struct cpunode_softc * const psc = device_private(parent); struct pq3ehci_softc * const sc = device_private(self); struct cpunode_attach_args * const cna = aux; struct cpunode_locators * const cnl = &cna->cna_locs; int error; psc->sc_children |= cna->cna_childmask; sc->sc.iot = cna->cna_le_memt; /* EHCI registers are little endian */ sc->sc.sc_dev = self; sc->sc.sc_bus.ub_dmatag = cna->cna_dmat; sc->sc.sc_bus.ub_hcpriv = sc; sc->sc.sc_bus.ub_revision = USBREV_2_0; sc->sc.sc_ncomp = 0; sc->sc.sc_flags |= EHCIF_ETTF; sc->sc.sc_vendor_init = pq3ehci_init; aprint_naive(": USB controller\n"); aprint_normal(": USB controller\n"); error = bus_space_map(sc->sc.iot, cnl->cnl_addr, cnl->cnl_size, 0, &sc->sc.ioh); if (error) { aprint_error_dev(self, "can't map registers for %s#%u: %d\n", cnl->cnl_name, cnl->cnl_instance, error); return; } sc->sc.sc_size = cnl->cnl_size; /* * We need to tell the USB interface to snoop all off RAM starting * at 0. Since it can do it by powers of 2, get the highest RAM * address and roughly round it to the next power of 2 and find * the number of leading zero bits. */ cpu_write_4(cnl->cnl_addr + USB_SNOOP1, SNOOP_2GB - __builtin_clz(curcpu()->ci_softc->cpu_highmem * 2 - 1)); cpu_write_4(cnl->cnl_addr + USB_CONTROL, USB_EN); sc->sc_ih = intr_establish(cnl->cnl_intrs[0], IPL_USB, IST_ONCHIP, ehci_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "failed to establish interrupt %d\n", cnl->cnl_intrs[0]); goto fail; } aprint_normal_dev(self, "interrupting on irq %d\n", cnl->cnl_intrs[0]); /* offs is needed for EOWRITEx */ sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); /* Disable interrupts, so we don't get any spurious ones. */ DPRINTF(("%s: offs=%d\n", device_xname(self), sc->sc.sc_offs)); EOWRITE4(&sc->sc, EHCI_USBINTR, 0); error = ehci_init(&sc->sc); if (error) { aprint_error_dev(self, "init failed, error=%d\n", error); goto fail; } /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); return; fail: if (sc->sc_ih) { intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; } if (sc->sc.sc_size) { bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); sc->sc.sc_size = 0; } return; }
static void ne_intio_attach(device_t parent, device_t self, void *aux) { struct ne_intio_softc *sc = device_private(self); struct dp8390_softc *dsc = &sc->sc_dp8390; struct intio_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_bst; bus_space_handle_t ioh; bus_space_tag_t asict; bus_space_handle_t asich; const char *typestr; int netype; dsc->sc_dev = self; aprint_normal(": Nereid Ethernet\n"); /* Map I/O space */ if (bus_space_map(iot, ia->ia_addr, NE2000_NPORTS*2, BUS_SPACE_MAP_SHIFTED_EVEN, &ioh)){ aprint_error_dev(self, "can't map I/O space\n"); return; } asict = iot; if (bus_space_subregion(iot, ioh, NE2000_ASIC_OFFSET*2, NE2000_ASIC_NPORTS*2, &asich)) { aprint_error_dev(self, "can't subregion I/O space\n"); return; } dsc->sc_regt = iot; dsc->sc_regh = ioh; sc->sc_asict = asict; sc->sc_asich = asich; /* * detect it again, so we can print some information about * the interface. * XXX: Should I check NE1000 or NE2000 for Nereid? */ netype = ne2000_detect(iot, ioh, asict, asich); switch (netype) { case NE2000_TYPE_NE1000: typestr = "NE1000"; break; case NE2000_TYPE_NE2000: typestr = "NE2000"; break; case NE2000_TYPE_RTL8019: typestr = "NE2000 (RTL8019)"; break; default: aprint_error_dev(self, "where did the card go?!\n"); return; } aprint_normal_dev(self, "%s Ethernet\n", typestr); /* This interface is always enabled */ dsc->sc_enabled = 1; /* * Do generic NE2000 attach. * This will read the mac address from the EEPROM. */ ne2000_attach(sc, NULL); /* Establish the interrupt handler */ if (intio_intr_establish(ia->ia_intr, "ne", dp8390_intr, dsc)) aprint_error_dev(self, "couldn't establish interrupt handler\n"); }
static void seeprom_attach(device_t parent, device_t self, void *aux) { struct seeprom_softc *sc = device_private(self); struct i2c_attach_args *ia = aux; sc->sc_tag = ia->ia_tag; sc->sc_address = ia->ia_addr; sc->sc_dev = self; if (ia->ia_name != NULL) { aprint_naive(": %s", ia->ia_name); aprint_normal(": %s", ia->ia_name); } else { aprint_naive(": EEPROM"); aprint_normal(": AT24Cxx or compatible EEPROM"); } /* * The AT24C01A/02/04/08/16 EEPROMs use a 1 byte command * word to select the offset into the EEPROM page. The * AT24C04/08/16 decode fewer of the i2c address bits, * using the bottom 1, 2, or 3 to select the 256-byte * super-page. * * The AT24C32/64/128/256/512 EEPROMs use a 2 byte command * word and decode all of the i2c address bits. * * The AT24C1024 EEPROMs use a 2 byte command and also do bank * switching to select the proper super-page. This isn't * supported by this driver. */ if (device_cfdata(self)->cf_flags) sc->sc_size = (device_cfdata(self)->cf_flags << 7); else sc->sc_size = ia->ia_size; switch (sc->sc_size) { case 128: /* 1Kbit */ case 256: /* 2Kbit */ case 512: /* 4Kbit */ case 1024: /* 8Kbit */ case 2048: /* 16Kbit */ sc->sc_cmdlen = 1; aprint_normal(": size %d\n", sc->sc_size); break; case 4096: /* 32Kbit */ case 8192: /* 64Kbit */ case 16384: /* 128Kbit */ case 32768: /* 256Kbit */ case 65536: /* 512Kbit */ sc->sc_cmdlen = 2; aprint_normal(": size %d\n", sc->sc_size); break; default: /* * Default to 2KB. If we happen to have a 2KB * EEPROM this will allow us to access it. If we * have a smaller one, the worst that can happen * is that we end up trying to read a different * EEPROM on the bus when accessing it. * * Obviously this will not work for 4KB or 8KB * EEPROMs, but them's the breaks. */ aprint_normal("\n"); aprint_error_dev(self, "invalid size specified; " "assuming 2KB (16Kb)\n"); sc->sc_size = 2048; sc->sc_cmdlen = 1; } sc->sc_open = 0; }
int mpt_dma_mem_alloc(mpt_softc_t *mpt) { bus_dma_segment_t reply_seg, request_seg; int reply_rseg, request_rseg; bus_addr_t pptr, end; char *vptr; size_t len; int error, i; /* Check if we have already allocated the reply memory. */ if (mpt->reply != NULL) return (0); /* * Allocate the request pool. This isn't really DMA'd memory, * but it's a convenient place to do it. */ len = sizeof(request_t) * MPT_MAX_REQUESTS(mpt); mpt->request_pool = malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); if (mpt->request_pool == NULL) { aprint_error_dev(mpt->sc_dev, "unable to allocate request pool\n"); return (ENOMEM); } /* * Allocate DMA resources for reply buffers. */ error = bus_dmamem_alloc(mpt->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, &reply_seg, 1, &reply_rseg, 0); if (error) { aprint_error_dev(mpt->sc_dev, "unable to allocate reply area, error = %d\n", error); goto fail_0; } error = bus_dmamem_map(mpt->sc_dmat, &reply_seg, reply_rseg, PAGE_SIZE, (void **) &mpt->reply, BUS_DMA_COHERENT/*XXX*/); if (error) { aprint_error_dev(mpt->sc_dev, "unable to map reply area, error = %d\n", error); goto fail_1; } error = bus_dmamap_create(mpt->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0, 0, &mpt->reply_dmap); if (error) { aprint_error_dev(mpt->sc_dev, "unable to create reply DMA map, error = %d\n", error); goto fail_2; } error = bus_dmamap_load(mpt->sc_dmat, mpt->reply_dmap, mpt->reply, PAGE_SIZE, NULL, 0); if (error) { aprint_error_dev(mpt->sc_dev, "unable to load reply DMA map, error = %d\n", error); goto fail_3; } mpt->reply_phys = mpt->reply_dmap->dm_segs[0].ds_addr; /* * Allocate DMA resources for request buffers. */ error = bus_dmamem_alloc(mpt->sc_dmat, MPT_REQ_MEM_SIZE(mpt), PAGE_SIZE, 0, &request_seg, 1, &request_rseg, 0); if (error) { aprint_error_dev(mpt->sc_dev, "unable to allocate request area, " "error = %d\n", error); goto fail_4; } error = bus_dmamem_map(mpt->sc_dmat, &request_seg, request_rseg, MPT_REQ_MEM_SIZE(mpt), (void **) &mpt->request, 0); if (error) { aprint_error_dev(mpt->sc_dev, "unable to map request area, error = %d\n", error); goto fail_5; } error = bus_dmamap_create(mpt->sc_dmat, MPT_REQ_MEM_SIZE(mpt), 1, MPT_REQ_MEM_SIZE(mpt), 0, 0, &mpt->request_dmap); if (error) { aprint_error_dev(mpt->sc_dev, "unable to create request DMA map, " "error = %d\n", error); goto fail_6; } error = bus_dmamap_load(mpt->sc_dmat, mpt->request_dmap, mpt->request, MPT_REQ_MEM_SIZE(mpt), NULL, 0); if (error) { aprint_error_dev(mpt->sc_dev, "unable to load request DMA map, error = %d\n", error); goto fail_7; } mpt->request_phys = mpt->request_dmap->dm_segs[0].ds_addr; pptr = mpt->request_phys; vptr = (void *) mpt->request; end = pptr + MPT_REQ_MEM_SIZE(mpt); for (i = 0; pptr < end; i++) { request_t *req = &mpt->request_pool[i]; req->index = i; /* Store location of Request Data */ req->req_pbuf = pptr; req->req_vbuf = vptr; pptr += MPT_REQUEST_AREA; vptr += MPT_REQUEST_AREA; req->sense_pbuf = (pptr - MPT_SENSE_SIZE); req->sense_vbuf = (vptr - MPT_SENSE_SIZE); error = bus_dmamap_create(mpt->sc_dmat, MAXPHYS, MPT_SGL_MAX, MAXPHYS, 0, 0, &req->dmap); if (error) { aprint_error_dev(mpt->sc_dev, "unable to create req %d DMA map, " "error = %d\n", i, error); goto fail_8; } } return (0); fail_8: for (--i; i >= 0; i--) { request_t *req = &mpt->request_pool[i]; if (req->dmap != NULL) bus_dmamap_destroy(mpt->sc_dmat, req->dmap); } bus_dmamap_unload(mpt->sc_dmat, mpt->request_dmap); fail_7: bus_dmamap_destroy(mpt->sc_dmat, mpt->request_dmap); fail_6: bus_dmamem_unmap(mpt->sc_dmat, (void *)mpt->request, PAGE_SIZE); fail_5: bus_dmamem_free(mpt->sc_dmat, &request_seg, request_rseg); fail_4: bus_dmamap_unload(mpt->sc_dmat, mpt->reply_dmap); fail_3: bus_dmamap_destroy(mpt->sc_dmat, mpt->reply_dmap); fail_2: bus_dmamem_unmap(mpt->sc_dmat, (void *)mpt->reply, PAGE_SIZE); fail_1: bus_dmamem_free(mpt->sc_dmat, &reply_seg, reply_rseg); fail_0: free(mpt->request_pool, M_DEVBUF); mpt->reply = NULL; mpt->request = NULL; mpt->request_pool = NULL; return (error); }
static void awin_gige_attach(device_t parent, device_t self, void *aux) { struct awin_gige_softc * const sc = device_private(self); struct awinio_attach_args * const aio = aux; const struct awin_locators * const loc = &aio->aio_loc; struct awin_gpio_pinset pinset; prop_dictionary_t cfg = device_properties(self); uint32_t clkreg; const char *phy_type, *pin_name; bus_space_handle_t bsh; switch (awin_chip_id()) { case AWIN_CHIP_ID_A80: bsh = aio->aio_a80_core2_bsh; pinset = awin_gige_gpio_pinset_a80; break; case AWIN_CHIP_ID_A31: bsh = aio->aio_core_bsh; pinset = awin_gige_gpio_pinset_a31; break; default: bsh = aio->aio_core_bsh; pinset = awin_gige_gpio_pinset; break; } sc->sc_core.sc_dev = self; prop_dictionary_get_uint8(cfg, "pinset-func", &pinset.pinset_func); awin_gpio_pinset_acquire(&pinset); sc->sc_core.sc_bst = aio->aio_core_bst; sc->sc_core.sc_dmat = aio->aio_dmat; bus_space_subregion(sc->sc_core.sc_bst, bsh, loc->loc_offset, loc->loc_size, &sc->sc_core.sc_bsh); aprint_naive("\n"); aprint_normal(": Gigabit Ethernet Controller\n"); awin_gige_pmu_init(self); /* * Interrupt handler */ sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_LEVEL, awin_gige_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "failed to establish interrupt %d\n", loc->loc_intr); return; } aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr); if (prop_dictionary_get_cstring_nocopy(cfg, "phy-power", &pin_name)) { if (awin_gpio_pin_reserve(pin_name, &sc->sc_power_pin)) { awin_gpio_pindata_write(&sc->sc_power_pin, 1); } else { aprint_error_dev(self, "failed to reserve GPIO \"%s\"\n", pin_name); } } /* * Enable GMAC clock */ if (awin_chip_id() == AWIN_CHIP_ID_A80) { awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, AWIN_A80_CCU_SCLK_BUS_CLK_GATING1_REG, AWIN_A80_CCU_SCLK_BUS_CLK_GATING1_GMAC, 0); } else if (awin_chip_id() == AWIN_CHIP_ID_A31) { awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, AWIN_AHB_GATING0_REG, AWIN_A31_AHB_GATING0_GMAC, 0); } else if (awin_chip_id() == AWIN_CHIP_ID_A20) { awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, AWIN_AHB_GATING1_REG, AWIN_AHB_GATING1_GMAC, 0); } /* * Soft reset */ if (awin_chip_id() == AWIN_CHIP_ID_A80) { awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, AWIN_A80_CCU_SCLK_BUS_SOFT_RST1_REG, AWIN_A80_CCU_SCLK_BUS_SOFT_RST1_GMAC, 0); } else if (awin_chip_id() == AWIN_CHIP_ID_A31) { awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, AWIN_A31_AHB_RESET0_REG, AWIN_A31_AHB_RESET0_GMAC_RST, 0); } /* * PHY clock setup */ if (!prop_dictionary_get_cstring_nocopy(cfg, "phy-type", &phy_type)) phy_type = "rgmii"; if (strcmp(phy_type, "rgmii") == 0) { clkreg = AWIN_GMAC_CLK_PIT | AWIN_GMAC_CLK_TCS_INT_RGMII; } else if (strcmp(phy_type, "rgmii-bpi") == 0) { clkreg = AWIN_GMAC_CLK_PIT | AWIN_GMAC_CLK_TCS_INT_RGMII; /* * These magic bits seem to be necessary for RGMII at gigabit * speeds on Banana Pi. */ clkreg |= __BITS(11,10); } else if (strcmp(phy_type, "gmii") == 0) { clkreg = AWIN_GMAC_CLK_TCS_INT_RGMII; } else if (strcmp(phy_type, "mii") == 0) { clkreg = AWIN_GMAC_CLK_TCS_MII; } else { panic("unknown phy type '%s'", phy_type); } if (awin_chip_id() == AWIN_CHIP_ID_A80) { awin_reg_set_clear(aio->aio_core_bst, aio->aio_a80_core2_bsh, AWIN_A80_SYS_CTRL_OFFSET + AWIN_A80_SYS_CTRL_EMAC_CLK_REG, clkreg, AWIN_GMAC_CLK_PIT|AWIN_GMAC_CLK_TCS); } else if (awin_chip_id() == AWIN_CHIP_ID_A31) { awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, AWIN_A31_GMAC_CLK_REG, clkreg, AWIN_GMAC_CLK_PIT|AWIN_GMAC_CLK_TCS); } else { awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, AWIN_GMAC_CLK_REG, clkreg, AWIN_GMAC_CLK_PIT|AWIN_GMAC_CLK_TCS); } dwc_gmac_attach(&sc->sc_core, GMAC_MII_CLK_150_250M_DIV102); }
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; }
/* * ym_acpi_attach: autoconf(9) attach routine */ static void ym_acpi_attach(struct device *parent, struct device *self, void *aux) { struct ym_softc *sc = (struct ym_softc *)self; struct acpi_attach_args *aa = aux; struct acpi_resources res; struct acpi_io *sb_io, *codec_io, *opl_io, *control_io; #if NMPU_YM > 0 struct acpi_io *mpu_io; #endif struct acpi_irq *irq; struct acpi_drq *playdrq, *recdrq; struct ad1848_softc *ac = &sc->sc_ad1848.sc_ad1848; ACPI_STATUS rv; aprint_naive("\n"); aprint_normal("\n"); /* Parse our resources */ rv = acpi_resource_parse(&sc->sc_ad1848.sc_ad1848.sc_dev, aa->aa_node->ad_handle, "_CRS", &res, &acpi_resource_parse_ops_default); if (ACPI_FAILURE(rv)) return; /* * sc_sb_ioh @ 0 * sc_ioh @ 1 * sc_opl_ioh @ 2 * sc_mpu_ioh @ 3 * sc_controlioh @ 4 */ /* Find and map our i/o registers */ sc->sc_iot = aa->aa_iot; sb_io = acpi_res_io(&res, 0); codec_io = acpi_res_io(&res, 1); opl_io = acpi_res_io(&res, 2); #if NMPU_YM > 0 mpu_io = acpi_res_io(&res, 3); #endif control_io = acpi_res_io(&res, 4); if (sb_io == NULL || codec_io == NULL || opl_io == NULL || #if NMPU_YM > 0 mpu_io == NULL || #endif control_io == NULL) { aprint_error_dev(self, "unable to find i/o registers resource\n"); goto out; } if (bus_space_map(sc->sc_iot, sb_io->ar_base, sb_io->ar_length, 0, &sc->sc_sb_ioh) != 0) { aprint_error_dev(self, "unable to map i/o registers (sb)\n"); goto out; } if (bus_space_map(sc->sc_iot, codec_io->ar_base, codec_io->ar_length, 0, &sc->sc_ioh) != 0) { aprint_error_dev(self, "unable to map i/o registers (codec)\n"); goto out; } if (bus_space_map(sc->sc_iot, opl_io->ar_base, opl_io->ar_length, 0, &sc->sc_opl_ioh) != 0) { aprint_error_dev(self, "unable to map i/o registers (opl)\n"); goto out; } #if NMPU_YM > 0 if (bus_space_map(sc->sc_iot, mpu_io->ar_base, mpu_io->ar_length, 0, &sc->sc_mpu_ioh) != 0) { aprint_error_dev(self, "unable to map i/o registers (mpu)\n"); goto out; } #endif if (bus_space_map(sc->sc_iot, control_io->ar_base, control_io->ar_length, 0, &sc->sc_controlioh) != 0) { aprint_error_dev(self, "unable to map i/o registers (control)\n"); goto out; } sc->sc_ic = aa->aa_ic; /* Find our IRQ */ irq = acpi_res_irq(&res, 0); if (irq == NULL) { aprint_error_dev(self, "unable to find irq resource\n"); /* XXX bus_space_unmap */ goto out; } sc->ym_irq = irq->ar_irq; /* Find our playback and record DRQs */ playdrq = acpi_res_drq(&res, 0); recdrq = acpi_res_drq(&res, 1); if (playdrq == NULL) { aprint_error_dev(self, "unable to find drq resources\n"); /* XXX bus_space_unmap */ goto out; } if (recdrq == NULL) { /* half-duplex mode */ sc->ym_recdrq = sc->ym_playdrq = playdrq->ar_drq; } else { sc->ym_playdrq = playdrq->ar_drq; sc->ym_recdrq = recdrq->ar_drq; } ac->sc_iot = sc->sc_iot; if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, WSS_CODEC, AD1848_NPORT, &ac->sc_ioh)) { aprint_error_dev(self, "bus_space_subregion failed\n"); /* XXX cleanup */ goto out; } aprint_normal_dev(self, ""); ac->mode = 2; ac->MCE_bit = MODE_CHANGE_ENABLE; sc->sc_ad1848.sc_ic = sc->sc_ic; /* Attach our ym device */ ym_attach(sc); out: acpi_resource_cleanup(&res); }
static void piixpm_attach(device_t parent, device_t self, void *aux) { struct piixpm_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct i2cbus_attach_args iba; pcireg_t base, conf; pcireg_t pmmisc; pci_intr_handle_t ih; char devinfo[256]; const char *intrstr = NULL; sc->sc_dev = self; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; aprint_naive("\n"); aprint_normal("\n"); pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); if (!pmf_device_register(self, piixpm_suspend, piixpm_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Read configuration */ conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); DPRINTF(("%s: conf 0x%x\n", device_xname(self), conf)); if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) || (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC)) goto nopowermanagement; /* check whether I/O access to PM regs is enabled */ pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC); if (!(pmmisc & 1)) goto nopowermanagement; sc->sc_pm_iot = pa->pa_iot; /* Map I/O space */ base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE); if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base), PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) { aprint_error_dev(self, "can't map power management I/O space\n"); goto nopowermanagement; } /* * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 * in the "Specification update" (document #297738). */ acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR, (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0 ); nopowermanagement: if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { aprint_normal_dev(self, "SMBus disabled\n"); return; } /* Map I/O space */ sc->sc_smb_iot = pa->pa_iot; base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff; if (bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base), PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) { aprint_error_dev(self, "can't map smbus I/O space\n"); return; } sc->sc_poll = 1; if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI) { /* No PCI IRQ */ aprint_normal_dev(self, "interrupting at SMI"); } else if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) { /* Install interrupt handler */ if (pci_intr_map(pa, &ih) == 0) { intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_smb_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, piixpm_intr, sc); if (sc->sc_smb_ih != NULL) { aprint_normal_dev(self, "interrupting at %s", intrstr); sc->sc_poll = 0; } } } if (sc->sc_poll) aprint_normal_dev(self, "polling"); aprint_normal("\n"); /* Attach I2C bus */ rw_init(&sc->sc_i2c_rwlock); sc->sc_i2c_tag.ic_cookie = sc; sc->sc_i2c_tag.ic_acquire_bus = piixpm_i2c_acquire_bus; sc->sc_i2c_tag.ic_release_bus = piixpm_i2c_release_bus; sc->sc_i2c_tag.ic_exec = piixpm_i2c_exec; bzero(&iba, sizeof(iba)); iba.iba_tag = &sc->sc_i2c_tag; config_found_ia(self, "i2cbus", &iba, iicbus_print); return; }
/* * ralink_ohci_attach */ static void ralink_ohci_attach(device_t parent, device_t self, void *aux) { struct ralink_ohci_softc * const sc = device_private(self); const struct mainbus_attach_args * const ma = aux; usbd_status status; int error; #ifdef RALINK_OHCI_DEBUG const char * const devname = device_xname(self); #endif aprint_naive(": OHCI USB controller\n"); aprint_normal(": OHCI USB controller\n"); sc->sc_ohci.sc_dev = self; sc->sc_ohci.sc_bus.hci_private = sc; sc->sc_ohci.iot = ma->ma_memt; sc->sc_ohci.sc_bus.dmatag = ma->ma_dmat; /* Map I/O registers */ if ((error = bus_space_map(sc->sc_ohci.iot, RA_USB_OHCI_BASE, RA_USB_BLOCK_SIZE, 0, &sc->sc_ohci.ioh)) != 0) { aprint_error_dev(self, "can't map OHCI registers, " "error=%d\n", error); return; } sc->sc_ohci.sc_size = RA_USB_BLOCK_SIZE; #ifdef RALINK_OHCI_DEBUG printf("%s sc: %p ma: %p\n", devname, sc, ma); printf("%s memt: %p dmat: %p\n", devname, ma->ma_memt, ma->ma_dmat); printf("%s: OHCI HcRevision=0x%x\n", devname, OREAD4(&sc->sc_ohci, OHCI_REVISION)); printf("%s: OHCI HcControl=0x%x\n", devname, OREAD4(&sc->sc_ohci, OHCI_CONTROL)); printf("%s: OHCI HcCommandStatus=0x%x\n", devname, OREAD4(&sc->sc_ohci, OHCI_COMMAND_STATUS)); printf("%s: OHCI HcInterruptStatus=0x%x\n", devname, OREAD4(&sc->sc_ohci, OHCI_INTERRUPT_STATUS)); #endif /* Disable OHCI interrupts. */ OWRITE4(&sc->sc_ohci, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); /* establish the MIPS level interrupt */ sc->sc_ih = ra_intr_establish(RA_IRQ_USB, ohci_intr, sc, 0); if (sc->sc_ih == NULL) { aprint_error_dev(self, "unable to establish irq %d\n", RA_IRQ_USB); goto fail_0; } /* Set vendor for root hub descriptor. */ sc->sc_ohci.sc_id_vendor = 0x1814; strlcpy(sc->sc_ohci.sc_vendor, "Ralink", sizeof(sc->sc_ohci.sc_vendor)); /* Initialize OHCI */ status = ohci_init(&sc->sc_ohci); if (status != USBD_NORMAL_COMPLETION) { aprint_error_dev(self, "init failed, error=%d\n", status); goto fail_0; } #if NEHCI > 0 ralink_usb_hc_add(&sc->sc_hc, self); #endif if (!pmf_device_register1(self, ohci_suspend, ohci_resume, ohci_shutdown)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Attach usb device. */ sc->sc_ohci.sc_child = config_found(self, &sc->sc_ohci.sc_bus, usbctlprint); return; fail_0: bus_space_unmap(sc->sc_ohci.iot, sc->sc_ohci.ioh, sc->sc_ohci.sc_size); sc->sc_ohci.sc_size = 0; }
static int piixpm_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags) { struct piixpm_softc *sc = cookie; const u_int8_t *b; u_int8_t ctl = 0, st; int retries; DPRINTF(("%s: exec: op %d, addr 0x%x, cmdlen %d, len %d, flags 0x%x\n", device_xname(sc->sc_dev), op, addr, cmdlen, len, flags)); /* Wait for bus to be idle */ for (retries = 100; retries > 0; retries--) { st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS); if (!(st & PIIX_SMB_HS_BUSY)) break; DELAY(PIIXPM_DELAY); } DPRINTF(("%s: exec: st 0x%d\n", device_xname(sc->sc_dev), st & 0xff)); if (st & PIIX_SMB_HS_BUSY) return (1); if (cold || sc->sc_poll) flags |= I2C_F_POLL; if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 2) return (1); /* Setup transfer */ sc->sc_i2c_xfer.op = op; sc->sc_i2c_xfer.buf = buf; sc->sc_i2c_xfer.len = len; sc->sc_i2c_xfer.flags = flags; sc->sc_i2c_xfer.error = 0; /* Set slave address and transfer direction */ bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_TXSLVA, PIIX_SMB_TXSLVA_ADDR(addr) | (I2C_OP_READ_P(op) ? PIIX_SMB_TXSLVA_READ : 0)); b = cmdbuf; if (cmdlen > 0) /* Set command byte */ bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HCMD, b[0]); if (I2C_OP_WRITE_P(op)) { /* Write data */ b = buf; if (len > 0) bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HD0, b[0]); if (len > 1) bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HD1, b[1]); } /* Set SMBus command */ if (len == 0) ctl = PIIX_SMB_HC_CMD_BYTE; else if (len == 1) ctl = PIIX_SMB_HC_CMD_BDATA; else if (len == 2) ctl = PIIX_SMB_HC_CMD_WDATA; if ((flags & I2C_F_POLL) == 0) ctl |= PIIX_SMB_HC_INTREN; /* Start transaction */ ctl |= PIIX_SMB_HC_START; bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HC, ctl); if (flags & I2C_F_POLL) { /* Poll for completion */ DELAY(PIIXPM_DELAY); for (retries = 1000; retries > 0; retries--) { st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS); if ((st & PIIX_SMB_HS_BUSY) == 0) break; DELAY(PIIXPM_DELAY); } if (st & PIIX_SMB_HS_BUSY) goto timeout; piixpm_intr(sc); } else { /* Wait for interrupt */ if (tsleep(sc, PRIBIO, "iicexec", PIIXPM_TIMEOUT * hz)) goto timeout; } if (sc->sc_i2c_xfer.error) return (1); return (0); timeout: /* * Transfer timeout. Kill the transaction and clear status bits. */ aprint_error_dev(sc->sc_dev, "timeout, status 0x%x\n", st); bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HC, PIIX_SMB_HC_KILL); DELAY(PIIXPM_DELAY); st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS); if ((st & PIIX_SMB_HS_FAILED) == 0) aprint_error_dev(sc->sc_dev, "transaction abort failed, status 0x%x\n", st); bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS, st); return (1); }
static void mppb_attach(device_t parent, device_t self, void *aux) { struct mppb_softc *sc; struct pcibus_attach_args pba; struct zbus_args *zap; pci_chipset_tag_t pc; #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; #endif /* PCI_NETBSD_CONFIGURE */ zap = aux; sc = device_private(self); pc = &sc->apc; sc->sc_dev = self; sc->ba = zap->va; aprint_normal(": Matay Prometheus PCI bridge\n"); /* Setup bus space mappings. */ sc->pci_conf_area.base = (bus_addr_t) sc->ba + MPPB_CONF_BASE; sc->pci_conf_area.absm = &amiga_bus_stride_1swap; sc->pci_mem_area.base = (bus_addr_t) sc->ba + MPPB_MEM_BASE; sc->pci_mem_area.absm = &amiga_bus_stride_1; sc->pci_io_area.base = (bus_addr_t) sc->ba + MPPB_IO_BASE; sc->pci_io_area.absm = &amiga_bus_stride_1; #ifdef MPPB_DEBUG aprint_normal("mppb mapped conf %x->%x, mem %x->%x\n, io %x->%x\n", kvtop((void*) sc->pci_conf_area.base), sc->pci_conf_area.base, kvtop((void*) sc->pci_mem_area.base), sc->pci_mem_area.base, kvtop((void*) sc->pci_io_area.base), sc->pci_io_area.base); #endif sc->apc.pci_conf_datat = &(sc->pci_conf_area); if (bus_space_map(sc->apc.pci_conf_datat, 0, MPPB_CONF_SIZE, 0, &sc->apc.pci_conf_datah)) aprint_error_dev(self, "couldn't map PCI configuration data space\n"); /* Initialize the PCI chipset tag. */ sc->apc.pc_conf_v = (void*) pc; sc->apc.pc_bus_maxdevs = mppb_pci_bus_maxdevs; sc->apc.pc_make_tag = amiga_pci_make_tag; sc->apc.pc_decompose_tag = amiga_pci_decompose_tag; sc->apc.pc_conf_read = mppb_pci_conf_read; sc->apc.pc_conf_write = mppb_pci_conf_write; sc->apc.pc_attach_hook = mppb_pci_attach_hook; sc->apc.pc_intr_map = mppb_pci_intr_map; sc->apc.pc_intr_string = amiga_pci_intr_string; sc->apc.pc_intr_establish = amiga_pci_intr_establish; sc->apc.pc_intr_disestablish = amiga_pci_intr_disestablish; sc->apc.pc_conf_hook = amiga_pci_conf_hook; sc->apc.pc_conf_interrupt = amiga_pci_conf_interrupt; #ifdef PCI_NETBSD_CONFIGURE ioext = extent_create("mppbio", MPPB_IO_BASE, MPPB_IO_BASE + MPPB_IO_SIZE, NULL, 0, EX_NOWAIT); memext = extent_create("mppbmem", MPPB_MEM_BASE, MPPB_MEM_BASE + MPPB_MEM_SIZE, NULL, 0, EX_NOWAIT); #ifdef MPPB_DEBUG aprint_normal("mppb: reconfiguring the bus!\n"); #endif /* MPPB_DEBUG */ pci_configure_bus(pc, ioext, memext, NULL, 0, CACHELINE_SIZE); extent_destroy(ioext); extent_destroy(memext); #endif /* PCI_NETBSD_CONFIGURE */ pba.pba_iot = &(sc->pci_io_area); pba.pba_memt = &(sc->pci_mem_area); pba.pba_dmat = NULL; pba.pba_dmat64 = NULL; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY; pba.pba_bus = 0; pba.pba_bridgetag = NULL; config_found_ia(self, "pcibus", &pba, pcibusprint); }
static void siisata_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct siisata_pci_softc *psc = device_private(self); struct siisata_softc *sc = &psc->si_sc; char devinfo[256]; const char *intrstr; pci_intr_handle_t intrhandle; pcireg_t csr, memtype; const struct siisata_pci_product *spp; void *ih; bus_space_tag_t memt; bus_space_handle_t memh; uint32_t gcreg; int memh_valid; bus_size_t grsize, prsize; sc->sc_atac.atac_dev = self; psc->sc_pc = pa->pa_pc; psc->sc_pcitag = pa->pa_tag; pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo)); aprint_naive(": SATA-II HBA\n"); aprint_normal(": %s\n", devinfo); /* map bar0 */ #if 1 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR0); #else memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; #endif switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: memh_valid = (pci_mapreg_map(pa, SIISATA_PCI_BAR0, memtype, 0, &memt, &memh, NULL, &grsize) == 0); break; default: memh_valid = 0; } if (memh_valid) { sc->sc_grt = memt; sc->sc_grh = memh; } else { aprint_error("%s: unable to map device global registers\n", SIISATANAME(sc)); return; } /* map bar1 */ #if 1 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR1); #else memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; #endif switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: memh_valid = (pci_mapreg_map(pa, SIISATA_PCI_BAR1, memtype, 0, &memt, &memh, NULL, &prsize) == 0); break; default: memh_valid = 0; } if (memh_valid) { sc->sc_prt = memt; sc->sc_prh = memh; } else { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); aprint_error("%s: unable to map device port registers\n", SIISATANAME(sc)); return; } if (pci_dma64_available(pa)) { sc->sc_dmat = pa->pa_dmat64; sc->sc_have_dma64 = 1; aprint_debug("64-bit PCI DMA available\n"); } else { sc->sc_dmat = pa->pa_dmat; sc->sc_have_dma64 = 0; } /* map interrupt */ if (pci_intr_map(pa, &intrhandle) != 0) { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize); aprint_error("%s: couldn't map interrupt\n", SIISATANAME(sc)); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, siisata_intr, sc); if (ih == NULL) { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize); aprint_error("%s: couldn't establish interrupt" "at %s\n", SIISATANAME(sc), intrstr); return; } aprint_normal("%s: interrupting at %s\n", SIISATANAME(sc), intrstr ? intrstr : "unknown interrupt"); /* fill in number of ports on this device */ spp = siisata_pci_lookup(pa); if (spp != NULL) { sc->sc_atac.atac_nchannels = spp->spp_ports; sc->sc_chip = spp->spp_chip; } else /* _match() should prevent us from getting here */ panic("siisata: the universe might be falling apart!\n"); gcreg = GRREAD(sc, GR_GC); aprint_normal("%s: SiI%d on ", SIISATANAME(sc), sc->sc_chip); if (sc->sc_chip == 3124) { aprint_normal("%d-bit, ", (gcreg & GR_GC_REQ64) ? 64 : 32); switch (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) { case 0: aprint_normal("%d", (gcreg & GR_GC_M66EN) ? 66 : 33); break; case GR_GC_TRDY: aprint_normal("%d", 66); break; case GR_GC_STOP: aprint_normal("%d", 100); break; case GR_GC_STOP | GR_GC_TRDY: aprint_normal("%d", 133); break; default: break; } aprint_normal("MHz PCI%s bus.", (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) ? "-X" : ""); } else { /* XXX - but only x1 devices so far */ aprint_normal("PCI-Express x1 port."); } if (gcreg & GR_GC_3GBPS) aprint_normal(" 3.0Gb/s capable.\n"); else aprint_normal("\n"); /* enable bus mastering in case the firmware didn't */ csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); csr |= PCI_COMMAND_MASTER_ENABLE; csr |= PCI_COMMAND_MEM_ENABLE; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr); siisata_attach(sc); if (!pmf_device_register(self, NULL, siisata_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); }
int an_attach(struct an_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &sc->sc_if; int i, s; struct an_rid_wepkey *akey; int buflen, kid, rid; int chan, chan_min, chan_max; s = splnet(); an_wait(sc); if (an_reset(sc) != 0) { config_deactivate(sc->sc_dev); splx(s); return 1; } /* Load factory config */ if (an_cmd(sc, AN_CMD_READCFG, 0) != 0) { splx(s); aprint_error_dev(sc->sc_dev, "failed to load config data\n"); return 1; } /* Read the current configuration */ buflen = sizeof(sc->sc_config); if (an_read_rid(sc, AN_RID_GENCONFIG, &sc->sc_config, &buflen) != 0) { splx(s); aprint_error_dev(sc->sc_dev, "read config failed\n"); return 1; } /* Read the card capabilities */ buflen = sizeof(sc->sc_caps); if (an_read_rid(sc, AN_RID_CAPABILITIES, &sc->sc_caps, &buflen) != 0) { splx(s); aprint_error_dev(sc->sc_dev, "read caps failed\n"); return 1; } #ifdef AN_DEBUG if (an_debug) { static const int dumprid[] = { AN_RID_GENCONFIG, AN_RID_CAPABILITIES, AN_RID_SSIDLIST, AN_RID_APLIST, AN_RID_STATUS, AN_RID_ENCAP }; for (rid = 0; rid < sizeof(dumprid)/sizeof(dumprid[0]); rid++) { buflen = sizeof(sc->sc_buf); if (an_read_rid(sc, dumprid[rid], &sc->sc_buf, &buflen) != 0) continue; printf("%04x (%d):\n", dumprid[rid], buflen); for (i = 0; i < (buflen + 1) / 2; i++) printf(" %04x", sc->sc_buf.sc_val[i]); printf("\n"); } } #endif /* Read WEP settings from persistent memory */ akey = &sc->sc_buf.sc_wepkey; buflen = sizeof(struct an_rid_wepkey); rid = AN_RID_WEP_VOLATILE; /* first persistent key */ while (an_read_rid(sc, rid, akey, &buflen) == 0) { kid = le16toh(akey->an_key_index); DPRINTF(("an_attach: wep rid=0x%x len=%d(%zu) index=0x%04x " "mac[0]=%02x keylen=%d\n", rid, buflen, sizeof(*akey), kid, akey->an_mac_addr[0], le16toh(akey->an_key_len))); if (kid == 0xffff) { sc->sc_tx_perskey = akey->an_mac_addr[0]; sc->sc_tx_key = -1; break; } if (kid >= IEEE80211_WEP_NKID) break; sc->sc_perskeylen[kid] = le16toh(akey->an_key_len); sc->sc_wepkeys[kid].an_wep_keylen = -1; rid = AN_RID_WEP_PERSISTENT; /* for next key */ buflen = sizeof(struct an_rid_wepkey); } aprint_normal_dev(sc->sc_dev, "%s %s (firmware %s)\n", sc->sc_caps.an_manufname, sc->sc_caps.an_prodname, sc->sc_caps.an_prodvers); memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS | IFF_SIMPLEX | IFF_MULTICAST | IFF_ALLMULTI; ifp->if_ioctl = an_ioctl; ifp->if_start = an_start; ifp->if_init = an_init; ifp->if_stop = an_stop; ifp->if_watchdog = an_watchdog; IFQ_SET_READY(&ifp->if_snd); ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_DS; ic->ic_opmode = IEEE80211_M_STA; ic->ic_caps = IEEE80211_C_WEP | IEEE80211_C_PMGT | IEEE80211_C_IBSS | IEEE80211_C_MONITOR; ic->ic_state = IEEE80211_S_INIT; IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_caps.an_oemaddr); switch (le16toh(sc->sc_caps.an_regdomain)) { default: case AN_REGDOMAIN_USA: case AN_REGDOMAIN_CANADA: chan_min = 1; chan_max = 11; break; case AN_REGDOMAIN_EUROPE: case AN_REGDOMAIN_AUSTRALIA: chan_min = 1; chan_max = 13; break; case AN_REGDOMAIN_JAPAN: chan_min = 14; chan_max = 14; break; case AN_REGDOMAIN_SPAIN: chan_min = 10; chan_max = 11; break; case AN_REGDOMAIN_FRANCE: chan_min = 10; chan_max = 13; break; case AN_REGDOMAIN_JAPANWIDE: chan_min = 1; chan_max = 14; break; } for (chan = chan_min; chan <= chan_max; chan++) { ic->ic_channels[chan].ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B; } ic->ic_ibss_chan = &ic->ic_channels[chan_min]; aprint_normal("%s: 802.11 address: %s, channel: %d-%d\n", ifp->if_xname, ether_sprintf(ic->ic_myaddr), chan_min, chan_max); /* Find supported rate */ for (i = 0; i < sizeof(sc->sc_caps.an_rates); i++) { if (sc->sc_caps.an_rates[i] == 0) continue; ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[ ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates++] = sc->sc_caps.an_rates[i]; } /* * Call MI attach routine. */ if_attach(ifp); ieee80211_ifattach(ic); sc->sc_newstate = ic->ic_newstate; ic->ic_newstate = an_newstate; ieee80211_media_init(ic, an_media_change, an_media_status); /* * radiotap BPF device */ bpf_attach2(ifp, DLT_IEEE802_11_RADIO, sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf); memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu)); sc->sc_rxtap.ar_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu)); sc->sc_rxtap.ar_ihdr.it_present = htole32(AN_RX_RADIOTAP_PRESENT); memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu)); sc->sc_txtap.at_ihdr.it_len = htole16(sizeof(sc->sc_txtapu)); sc->sc_txtap.at_ihdr.it_present = htole32(AN_TX_RADIOTAP_PRESENT); sc->sc_attached = 1; splx(s); ieee80211_announce(ic); return 0; }
/* * Look for an Intel MP spec table, indicating SMP capable hardware. */ int mpbios_probe(device_t self) { paddr_t ebda, memtop; paddr_t cthpa; int cthlen; const uint8_t *mpbios_page; int scan_loc; struct mp_map t; /* If MP is disabled, don't use MPBIOS or the ioapics. */ if ((boothowto & RB_MD1) != 0) return 0; /* see if EBDA exists */ mpbios_page = mpbios_map (0, PAGE_SIZE, &t); ebda = *(const uint16_t *) (&mpbios_page[0x40e]); ebda <<= 4; memtop = *(const uint16_t *) (&mpbios_page[0x413]); memtop <<= 10; mpbios_page = NULL; mpbios_unmap(&t); scan_loc = 0; if (ebda && ebda < IOM_BEGIN ) { mp_fps = mpbios_search(self, ebda, 1024, &mp_fp_map); if (mp_fps != NULL) goto found; } scan_loc = 1; if (memtop && memtop <= IOM_BEGIN ) { mp_fps = mpbios_search(self, memtop - 1024, 1024, &mp_fp_map); if (mp_fps != NULL) goto found; } scan_loc = 2; mp_fps = mpbios_search(self, BIOS_BASE, BIOS_COUNT, &mp_fp_map); if (mp_fps != NULL) goto found; /* nothing found */ return 0; found: if (mp_verbose) aprint_verbose_dev(self, "MP floating pointer found in %s at 0x%jx\n", loc_where[scan_loc], (uintmax_t)mp_fp_map.pa); if (mp_fps->pap == 0) { if (mp_fps->mpfb1 == 0) { aprint_error_dev(self, "MP fps invalid: " "no default config and no configuration table\n"); goto err; } return 10; } cthpa = mp_fps->pap; mp_cth = mpbios_map (cthpa, sizeof (*mp_cth), &mp_cfg_table_map); cthlen = mp_cth->base_len; mpbios_unmap(&mp_cfg_table_map); mp_cth = mpbios_map (cthpa, cthlen, &mp_cfg_table_map); if (mp_verbose) aprint_verbose_dev(self, "MP config table at 0x%jx, %d bytes long\n", (uintmax_t)cthpa, cthlen); if (mp_cth->signature != MP_CT_SIG) { aprint_error_dev(self, "MP signature mismatch (%x vs %x)\n", MP_CT_SIG, mp_cth->signature); goto err; } if (mpbios_cksum(mp_cth, cthlen)) { aprint_error_dev(self, "MP Configuration Table checksum mismatch\n"); goto err; } return 10; err: if (mp_fps) { mp_fps = NULL; mpbios_unmap(&mp_fp_map); } if (mp_cth) { mp_cth = NULL; mpbios_unmap(&mp_cfg_table_map); } return 0; }
void ym_pnpbios_attach(device_t parent, device_t self, void *aux) { struct ym_softc *sc = device_private(self); struct ad1848_softc *ac = &sc->sc_ad1848.sc_ad1848; struct pnpbiosdev_attach_args *aa = aux; ac->sc_dev = self; if (pnpbios_io_map(aa->pbt, aa->resc, 0, &sc->sc_iot, &sc->sc_sb_ioh) != 0) { printf(": can't map sb i/o space\n"); return; } if (pnpbios_io_map(aa->pbt, aa->resc, 1, &sc->sc_iot, &sc->sc_ioh) != 0) { printf(": can't map sb i/o space\n"); return; } if (pnpbios_io_map(aa->pbt, aa->resc, 2, &sc->sc_iot, &sc->sc_opl_ioh) != 0) { printf(": can't map opl i/o space\n"); return; } #if NMPU_YM > 0 if (pnpbios_io_map(aa->pbt, aa->resc, 3, &sc->sc_iot, &sc->sc_mpu_ioh) != 0) { printf(": can't map mpu i/o space\n"); return; } #endif if (pnpbios_io_map(aa->pbt, aa->resc, 4, &sc->sc_iot, &sc->sc_controlioh) != 0) { printf(": can't map control i/o space\n"); return; } sc->sc_ic = aa->ic; if (pnpbios_getirqnum(aa->pbt, aa->resc, 0, &sc->ym_irq, NULL)) { printf(": can't get IRQ\n"); return; } if (pnpbios_getdmachan(aa->pbt, aa->resc, 0, &sc->ym_playdrq)) { printf(": can't get DMA channel\n"); return; } if (pnpbios_getdmachan(aa->pbt, aa->resc, 1, &sc->ym_recdrq)) sc->ym_recdrq = sc->ym_playdrq; /* half-duplex mode */ printf("\n"); pnpbios_print_devres(self, aa); printf("%s", device_xname(self)); ac->sc_iot = sc->sc_iot; if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, WSS_CODEC, AD1848_NPORT, &ac->sc_ioh)) { aprint_error_dev(self, "bus_space_subregion failed\n"); return; } ac->mode = 2; ac->MCE_bit = MODE_CHANGE_ENABLE; sc->sc_ad1848.sc_ic = sc->sc_ic; ym_attach(sc); }
/* * 1st pass on BIOS's Intel MP specification table. * * initializes: * mp_ncpus = 1 * * determines: * cpu_apic_address (common to all CPUs) * ioapic_address[N] * mp_naps * mp_nbus * mp_napics * nintrs */ void mpbios_scan(device_t self, int *ncpup) { const uint8_t *position, *end; size_t i; int count; int type; int intr_cnt, cur_intr; paddr_t lapic_base; const struct dflt_conf_entry *dflt_conf; const int *dflt_bus_irq; const struct mpbios_int *iep; struct mpbios_int ie; aprint_normal_dev(self, "Intel MP Specification "); switch (mp_fps->spec_rev) { case 1: aprint_normal("(Version 1.1)"); break; case 4: aprint_normal("(Version 1.4)"); break; default: aprint_normal("(unrecognized rev %d)", mp_fps->spec_rev); } /* * looks like we've got a MP system. start setting up * infrastructure.. * XXX is this the right place?? */ #if NACPICA > 0 if (mpacpi_ncpu == 0) { #endif lapic_base = LAPIC_BASE; if (mp_cth != NULL) lapic_base = (paddr_t)mp_cth->apic_address; #if NLAPIC > 0 lapic_boot_init(lapic_base); #endif #if NACPICA > 0 } #endif /* check for use of 'default' configuration */ if (mp_fps->mpfb1 != 0) { if (mp_fps->mpfb1 > __arraycount(dflt_conf_tab)) panic("Unsupported MP default configuration %d\n", mp_fps->mpfb1); aprint_normal("\n"); aprint_normal_dev(self, "MP default configuration %d\n", mp_fps->mpfb1); dflt_conf = &dflt_conf_tab[mp_fps->mpfb1 - 1]; dflt_bus_irq = dflt_bus_irq_tab[(dflt_conf->flags & IRQ_VAR) != 0]; #if NACPICA > 0 if (mpacpi_ncpu == 0) #endif mpbios_dflt_conf_cpu(self); #if NACPICA > 0 if (mpacpi_nioapic == 0) #endif mpbios_dflt_conf_ioapic(self); /* * Walk the table once, counting items. */ mp_nbus = 0; for (i = 0; i < __arraycount(dflt_conf->bus_type); i++) { if (dflt_conf->bus_type[i] != NULL) mp_nbus++; } KASSERT(mp_nbus != 0); mp_busses = kmem_zalloc(sizeof(struct mp_bus) * mp_nbus, KM_SLEEP); KASSERT(mp_busses != NULL); /* INTIN0 */ intr_cnt = (dflt_conf->flags & INTIN0_NC) ? 0 : 1; /* INTINx */ for (i = 0; i < __arraycount(dflt_bus_irq_tab[0]); i++) { if (dflt_bus_irq[i] >= 0) intr_cnt++; } KASSERT(intr_cnt != 0); /* LINTINx */ for (i = 0; i < __arraycount(dflt_lint_tab); i++) intr_cnt++; mp_intrs = kmem_zalloc(sizeof(struct mp_intr_map) * intr_cnt, KM_SLEEP); KASSERT(mp_intrs != NULL); mp_nintr = intr_cnt; /* * Re-walk the table, recording info of interest. */ mpbios_dflt_conf_bus(self, dflt_conf); mpbios_dflt_conf_int(self, dflt_conf, dflt_bus_irq); } else { /* * should not happen; mp_probe returns 0 in this case, * but.. */ if (mp_cth == NULL) panic ("mpbios_scan: no config (can't happen?)"); printf(" (%8.8s %12.12s)\n", mp_cth->oem_id, mp_cth->product_id); /* * Walk the table once, counting items */ position = (const uint8_t *)(mp_cth); end = position + mp_cth->base_len; position += sizeof(*mp_cth); count = mp_cth->entry_count; intr_cnt = 0; while ((count--) && (position < end)) { type = *position; if (type >= MPS_MCT_NTYPES) { aprint_error_dev(self, "unknown entry type %x" " in MP config table\n", type); break; } mp_conf[type].count++; if (type == MPS_MCT_BUS) { const struct mpbios_bus *bp = (const struct mpbios_bus *)position; if (bp->bus_id >= mp_nbus) mp_nbus = bp->bus_id + 1; } /* * Count actual interrupt instances. * dst_apic_id of MPS_ALL_APICS means "wired to all * apics of this type". */ if (type == MPS_MCT_IOINT) { iep = (const struct mpbios_int *)position; if (iep->dst_apic_id == MPS_ALL_APICS) intr_cnt += mp_conf[MPS_MCT_IOAPIC].count; else intr_cnt++; } else if (type == MPS_MCT_LINT) intr_cnt++; position += mp_conf[type].length; } mp_busses = kmem_zalloc(sizeof(struct mp_bus)*mp_nbus, KM_SLEEP); KASSERT(mp_busses != NULL); mp_intrs = kmem_zalloc(sizeof(struct mp_intr_map)*intr_cnt, KM_SLEEP); KASSERT(mp_intrs != NULL); mp_nintr = intr_cnt; /* re-walk the table, recording info of interest */ position = (const uint8_t *) mp_cth + sizeof(*mp_cth); count = mp_cth->entry_count; cur_intr = 0; while ((count--) && (position < end)) { switch (type = *position) { case MPS_MCT_CPU: #if NACPICA > 0 /* ACPI has done this for us */ if (mpacpi_ncpu) break; #endif mpbios_cpu(position, self); break; case MPS_MCT_BUS: mpbios_bus(position, self); break; case MPS_MCT_IOAPIC: #if NACPICA > 0 /* ACPI has done this for us */ if (mpacpi_nioapic) break; #endif mpbios_ioapic(position, self); break; case MPS_MCT_IOINT: iep = (const struct mpbios_int *)position; ie = *iep; if (iep->dst_apic_id == MPS_ALL_APICS) { #if NIOAPIC > 0 struct ioapic_softc *sc; for (sc = ioapics ; sc != NULL; sc = sc->sc_next) { ie.dst_apic_id = sc->sc_apicid; mpbios_int((char *)&ie, type, &mp_intrs[cur_intr++]); } #endif } else { mpbios_int(position, type, &mp_intrs[cur_intr++]); } break; case MPS_MCT_LINT: mpbios_int(position, type, &mp_intrs[cur_intr]); cur_intr++; break; default: aprint_error_dev(self, "unknown entry type %x in MP config table\n", type); /* NOTREACHED */ return; } position += mp_conf[type].length; } if (mp_verbose && mp_cth->ext_len) aprint_verbose_dev(self, "MP WARNING: %d bytes of extended entries not examined\n", mp_cth->ext_len); } /* Clean up. */ mp_fps = NULL; mpbios_unmap (&mp_fp_map); if (mp_cth != NULL) { mp_cth = NULL; mpbios_unmap (&mp_cfg_table_map); } mpbios_scanned = 1; *ncpup = mpbios_ncpu; }
/* * Attach a found zs. * * Match slave number to zs unit number, so that misconfiguration will * not set up the keyboard as ttya, etc. */ static void zs_hpc_attach(device_t parent, device_t self, void *aux) { struct zsc_softc *zsc = device_private(self); struct hpc_attach_args *haa = aux; struct zsc_attach_args zsc_args; struct zs_chanstate *cs; struct zs_channel *ch; int zs_unit, channel, err, s; const char *promconsdev; promconsdev = arcbios_GetEnvironmentVariable("ConsoleOut"); zsc->zsc_dev = self; zsc->zsc_bustag = haa->ha_st; if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh, haa->ha_devoff, 0x10, &zsc->zsc_base)) != 0) { aprint_error(": unable to map 85c30 registers, error = %d\n", err); return; } zs_unit = device_unit(self); aprint_normal("\n"); /* * Initialize software state for each channel. * * Done in reverse order of channels since the first serial port * is actually attached to the *second* channel, and vice versa. * Doing it this way should force a 'zstty*' to attach zstty0 to * channel 1 and zstty1 to channel 0. They couldn't have wired * it up in a more sensible fashion, could they? */ for (channel = 1; channel >= 0; channel--) { zsc_args.channel = channel; ch = &zsc->zsc_cs_store[channel]; cs = zsc->zsc_cs[channel] = (struct zs_chanstate *)ch; zs_lock_init(cs); cs->cs_reg_csr = NULL; cs->cs_reg_data = NULL; cs->cs_channel = channel; cs->cs_private = NULL; cs->cs_ops = &zsops_null; cs->cs_brg_clk = PCLK / 16; if (bus_space_subregion(zsc->zsc_bustag, zsc->zsc_base, zs_chan_offset[channel], sizeof(struct zschan), &ch->cs_regs) != 0) { aprint_error_dev(self, "cannot map regs\n"); return; } ch->cs_bustag = zsc->zsc_bustag; memcpy(cs->cs_creg, zs_init_reg, 16); memcpy(cs->cs_preg, zs_init_reg, 16); zsc_args.hwflags = 0; zsc_args.consdev = NULL; if (zs_consunit == -1 && zs_conschan == -1) { /* * If this channel is being used by the PROM console, * pass the generic zs driver a 'no reset' flag so the * channel gets left in the appropriate state after * attach. * * Note: the channel mappings are swapped. */ if (promconsdev != NULL && strlen(promconsdev) == 9 && strncmp(promconsdev, "serial", 6) == 0 && (promconsdev[7] == '0' || promconsdev[7] == '1')) { if (promconsdev[7] == '1' && channel == 0) zsc_args.hwflags |= ZS_HWFLAG_NORESET; else if (promconsdev[7] == '0' && channel == 1) zsc_args.hwflags |= ZS_HWFLAG_NORESET; } } /* If console, don't stomp speed, let zstty know */ if (zs_unit == zs_consunit && channel == zs_conschan) { zsc_args.consdev = &zs_cn; zsc_args.hwflags = ZS_HWFLAG_CONSOLE; cs->cs_defspeed = zs_get_speed(cs); } else cs->cs_defspeed = zs_defspeed; cs->cs_defcflag = zs_def_cflag; /* Make these correspond to cs_defcflag (-crtscts) */ cs->cs_rr0_dcd = ZSRR0_DCD; cs->cs_rr0_cts = 0; cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; cs->cs_wr5_rts = 0; /* * Clear the master interrupt enable. * The INTENA is common to both channels, * so just do it on the A channel. */ if (channel == 0) { zs_write_reg(cs, 9, 0); } /* * Look for a child driver for this channel. * The child attach will setup the hardware. */ if (!config_found(self, (void *)&zsc_args, zs_print)) { /* No sub-driver. Just reset it. */ uint8_t reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; s = splhigh(); zs_write_reg(cs, 9, reset); splx(s); } } zsc->sc_si = softint_establish(SOFTINT_SERIAL, zssoft, zsc); cpu_intr_establish(haa->ha_irq, IPL_TTY, zshard, NULL); evcnt_attach_dynamic(&zsc->zsc_intrcnt, EVCNT_TYPE_INTR, NULL, device_xname(self), "intr"); /* * Set the master interrupt enable and interrupt vector. * (common to both channels, do it on A) */ cs = zsc->zsc_cs[0]; s = splhigh(); /* interrupt vector */ zs_write_reg(cs, 2, zs_init_reg[2]); /* master interrupt control (enable) */ zs_write_reg(cs, 9, zs_init_reg[9]); splx(s); }
static int clmpcc_init(struct clmpcc_softc *sc) { u_int tcor = 0, tbpr = 0; u_int rcor = 0, rbpr = 0; u_int msvr_rts, msvr_dtr; u_int ccr; int is_console; int i; /* * All we're really concerned about here is putting the chip * into a quiescent state so that it won't do anything until * clmpccopen() is called. (Except the console channel.) */ /* * If the chip is acting as console, set all channels to the supplied * console baud rate. Otherwise, plump for 9600. */ if ( cons_sc && sc->sc_ioh == cons_sc->sc_ioh && sc->sc_iot == cons_sc->sc_iot ) { clmpcc_speed(sc, cons_rate, &tcor, &tbpr); clmpcc_speed(sc, cons_rate, &rcor, &rbpr); is_console = 1; } else { clmpcc_speed(sc, 9600, &tcor, &tbpr); clmpcc_speed(sc, 9600, &rcor, &rbpr); is_console = 0; } /* Allow any pending output to be sent */ delay(10000); /* Send the Reset All command to channel 0 (resets all channels!) */ clmpcc_channel_cmd(sc, 0, CLMPCC_CCR_T0_RESET_ALL); delay(1000); /* * The chip will set it's firmware revision register to a non-zero * value to indicate completion of reset. */ for (i = 10000; clmpcc_rdreg(sc, CLMPCC_REG_GFRCR) == 0 && i; i--) delay(1); if ( i == 0 ) { /* * Watch out... If this chip is console, the message * probably won't be sent since we just reset it! */ aprint_error_dev(sc->sc_dev, "Failed to reset chip\n"); return -1; } for (i = 0; i < CLMPCC_NUM_CHANS; i++) { clmpcc_select_channel(sc, i); /* All interrupts are disabled to begin with */ clmpcc_wrreg(sc, CLMPCC_REG_IER, 0); /* Make sure the channel interrupts on the correct vectors */ clmpcc_wrreg(sc, CLMPCC_REG_LIVR, sc->sc_vector_base); clmpcc_wr_pilr(sc, CLMPCC_REG_RPILR, sc->sc_rpilr); clmpcc_wr_pilr(sc, CLMPCC_REG_TPILR, sc->sc_tpilr); clmpcc_wr_pilr(sc, CLMPCC_REG_MPILR, sc->sc_mpilr); /* Receive timer prescaler set to 1ms */ clmpcc_wrreg(sc, CLMPCC_REG_TPR, CLMPCC_MSEC_TO_TPR(sc->sc_clk, 1)); /* We support Async mode only */ clmpcc_wrreg(sc, CLMPCC_REG_CMR, CLMPCC_CMR_ASYNC); /* Set the required baud rate */ clmpcc_wrreg(sc, CLMPCC_REG_TCOR, CLMPCC_TCOR_CLK(tcor)); clmpcc_wrreg(sc, CLMPCC_REG_TBPR, tbpr); clmpcc_wrreg(sc, CLMPCC_REG_RCOR, CLMPCC_RCOR_CLK(rcor)); clmpcc_wrreg(sc, CLMPCC_REG_RBPR, rbpr); /* Always default to 8N1 (XXX what about console?) */ clmpcc_wrreg(sc, CLMPCC_REG_COR1, CLMPCC_COR1_CHAR_8BITS | CLMPCC_COR1_NO_PARITY | CLMPCC_COR1_IGNORE_PAR); clmpcc_wrreg(sc, CLMPCC_REG_COR2, 0); clmpcc_wrreg(sc, CLMPCC_REG_COR3, CLMPCC_COR3_STOP_1); clmpcc_wrreg(sc, CLMPCC_REG_COR4, CLMPCC_COR4_DSRzd | CLMPCC_COR4_CDzd | CLMPCC_COR4_CTSzd); clmpcc_wrreg(sc, CLMPCC_REG_COR5, CLMPCC_COR5_DSRod | CLMPCC_COR5_CDod | CLMPCC_COR5_CTSod | CLMPCC_COR5_FLOW_NORM); clmpcc_wrreg(sc, CLMPCC_REG_COR6, 0); clmpcc_wrreg(sc, CLMPCC_REG_COR7, 0); /* Set the receive FIFO timeout */ clmpcc_wrreg(sc, CLMPCC_REG_RTPRl, CLMPCC_RTPR_DEFAULT); clmpcc_wrreg(sc, CLMPCC_REG_RTPRh, 0); /* At this point, we set up the console differently */ if ( is_console && i == cons_chan ) { msvr_rts = CLMPCC_MSVR_RTS; msvr_dtr = CLMPCC_MSVR_DTR; ccr = CLMPCC_CCR_T0_RX_EN | CLMPCC_CCR_T0_TX_EN; } else { msvr_rts = 0; msvr_dtr = 0; ccr = CLMPCC_CCR_T0_RX_DIS | CLMPCC_CCR_T0_TX_DIS; } clmpcc_wrreg(sc, CLMPCC_REG_MSVR_RTS, msvr_rts); clmpcc_wrreg(sc, CLMPCC_REG_MSVR_DTR, msvr_dtr); clmpcc_channel_cmd(sc, i, CLMPCC_CCR_T0_INIT | ccr); delay(100); } return 0; }