static void panel_attach(device_t parent, device_t self, void *aux) { struct panel_softc *sc = device_private(self); struct mainbus_attach_args *maa = aux; struct hd44780_io io; static struct lcdkp_xlate keys[] = { { 0xfa, 'h' }, { 0xf6, 'k' }, { 0xde, 'l' }, { 0xee, 'j' }, { 0x7e, 's' }, { 0xbe, 'e' } }; sc->sc_lcd.sc_dev = self; sc->sc_lcd.sc_iot = maa->ma_iot; if (bus_space_map(sc->sc_lcd.sc_iot, maa->ma_addr, PANEL_REGION, 0, &sc->sc_lcd.sc_ioir)) { aprint_error(": unable to map registers\n"); return; } bus_space_subregion(sc->sc_lcd.sc_iot, sc->sc_lcd.sc_ioir, DATA_OFFSET, 1, &sc->sc_lcd.sc_iodr); sc->sc_lcd.sc_dev_ok = 1; sc->sc_lcd.sc_cols = PANEL_COLS; sc->sc_lcd.sc_vcols = PANEL_VCOLS; sc->sc_lcd.sc_flags = HD_8BIT | HD_MULTILINE | HD_KEYPAD; sc->sc_lcd.sc_writereg = panel_cbt_hdwritereg; sc->sc_lcd.sc_readreg = panel_cbt_hdreadreg; hd44780_attach_subr(&sc->sc_lcd); /* Hello World */ io.dat = 0; io.len = PANEL_VCOLS * PANEL_ROWS; memcpy(io.buf, &startup_message, io.len); hd44780_ddram_io(&sc->sc_lcd, sc->sc_lcd.sc_curchip, &io, HD_DDRAM_WRITE); shutdownhook_establish(panel_shutdown, sc); sc->sc_kp.sc_iot = maa->ma_iot; sc->sc_kp.sc_ioh = MIPS_PHYS_TO_KSEG1(PANEL_BASE); /* XXX */ sc->sc_kp.sc_knum = sizeof(keys) / sizeof(struct lcdkp_xlate); sc->sc_kp.sc_kpad = keys; sc->sc_kp.sc_rread = panel_cbt_kprread; lcdkp_attach_subr(&sc->sc_kp); callout_init(&sc->sc_callout, 0); selinit(&sc->sc_selq); printf("\n"); }
void wdog_register(void *cb_arg, int (*cb)(void *, int)) { if (wdog_ctl_cb != NULL) return; wdog_ctl_cb = cb; wdog_ctl_cb_arg = cb_arg; timeout_set(&wdog_timeout, wdog_tickle, NULL); wdog_cookie = shutdownhook_establish(wdog_shutdown, NULL); }
static void slugled_defer(device_t self) { struct slugled_softc *sc = device_private(self); struct ixp425_softc *ixsc = ixp425_softc; uint32_t reg; int s; s = splhigh(); /* Configure LED GPIO pins as output */ reg = GPIO_CONF_READ_4(ixsc, IXP425_GPIO_GPOER); reg &= ~(LEDBITS_USB0 | LEDBITS_USB1); reg &= ~(LEDBITS_READY | LEDBITS_STATUS); GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPOER, reg); /* All LEDs off */ reg = GPIO_CONF_READ_4(ixsc, IXP425_GPIO_GPOUTR); reg |= LEDBITS_USB0 | LEDBITS_USB1; reg &= ~(LEDBITS_STATUS | LEDBITS_READY); GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPOUTR, reg); splx(s); if (shutdownhook_establish(slugled_shutdown, sc) == NULL) aprint_error_dev(self, "WARNING - Failed to register shutdown hook\n"); callout_init(&sc->sc_usb0, 0); callout_setfunc(&sc->sc_usb0, slugled_callout, (void *)(uintptr_t)LEDBITS_USB0); callout_init(&sc->sc_usb1, 0); callout_setfunc(&sc->sc_usb1, slugled_callout, (void *)(uintptr_t)LEDBITS_USB1); callout_init(&sc->sc_usb2, 0); callout_setfunc(&sc->sc_usb2, slugled_callout, (void *)(uintptr_t)(LEDBITS_USB0 | LEDBITS_USB1)); sc->sc_usb0_ih = ixp425_intr_establish(PCI_INT_A, IPL_USB, slugled_intr0, sc); KDASSERT(sc->sc_usb0_ih != NULL); sc->sc_usb1_ih = ixp425_intr_establish(PCI_INT_B, IPL_USB, slugled_intr1, sc); KDASSERT(sc->sc_usb1_ih != NULL); sc->sc_usb2_ih = ixp425_intr_establish(PCI_INT_C, IPL_USB, slugled_intr2, sc); KDASSERT(sc->sc_usb2_ih != NULL); sc->sc_tmr_ih = ixp425_intr_establish(IXP425_INT_TMR0, IPL_CLOCK, slugled_tmr, NULL); KDASSERT(sc->sc_tmr_ih != NULL); }
void ldattach(struct ld_softc *sc) { char buf[9]; if ((sc->sc_flags & LDF_ENABLED) == 0) { printf("%s: disabled\n", sc->sc_dv.dv_xname); return; } /* Initialise and attach the disk structure. */ sc->sc_dk.dk_driver = &lddkdriver; sc->sc_dk.dk_name = sc->sc_dv.dv_xname; disk_attach(&sc->sc_dk); if (sc->sc_maxxfer > MAXPHYS) sc->sc_maxxfer = MAXPHYS; /* Build synthetic geometry. */ if (sc->sc_secperunit <= 528 * 2048) /* 528MB */ sc->sc_nheads = 16; else if (sc->sc_secperunit <= 1024 * 2048) /* 1GB */ sc->sc_nheads = 32; else if (sc->sc_secperunit <= 21504 * 2048) /* 21GB */ sc->sc_nheads = 64; else if (sc->sc_secperunit <= 43008 * 2048) /* 42GB */ sc->sc_nheads = 128; else sc->sc_nheads = 255; sc->sc_nsectors = 63; sc->sc_ncylinders = sc->sc_secperunit / (sc->sc_nheads * sc->sc_nsectors); format_bytes(buf, sizeof(buf), (u_int64_t)sc->sc_secperunit * sc->sc_secsize); printf("%s: %s, %d cyl, %d head, %d sec, %d bytes/sect x %d sectors\n", sc->sc_dv.dv_xname, buf, sc->sc_ncylinders, sc->sc_nheads, sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit); #if NRND > 0 /* Attach the device into the rnd source list. */ rnd_attach_source(&sc->sc_rnd_source, sc->sc_dv.dv_xname, RND_TYPE_DISK, 0); #endif /* Set the `shutdownhook'. */ if (ld_sdh == NULL) ld_sdh = shutdownhook_establish(ldshutdown, NULL); BUFQ_INIT(&sc->sc_bufq); }
/* * sysmonopen_wdog: * * Open the system monitor device. */ int sysmonopen_wdog(dev_t dev, int flag, int mode, struct proc *p) { simple_lock(&sysmon_wdog_list_slock); if (sysmon_wdog_sdhook == NULL) { sysmon_wdog_sdhook = shutdownhook_establish(sysmon_wdog_shutdown, NULL); if (sysmon_wdog_sdhook == NULL) printf("WARNING: unable to register watchdog " "shutdown hook\n"); } simple_unlock(&sysmon_wdog_list_slock); return (0); }
int sysctl_wdog(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { int error, period; if (wdog_ctl_cb == NULL) return (EOPNOTSUPP); switch (name[0]) { case KERN_WATCHDOG_PERIOD: period = wdog_period; error = sysctl_int(oldp, oldlenp, newp, newlen, &period); if (error) return (error); if (newp) { timeout_del(&wdog_timeout); wdog_period = (*wdog_ctl_cb)(wdog_ctl_cb_arg, period); } break; case KERN_WATCHDOG_AUTO: error = sysctl_int(oldp, oldlenp, newp, newlen, &wdog_auto); if (error) return (error); if (wdog_auto && wdog_cookie == NULL) wdog_cookie = shutdownhook_establish(wdog_shutdown, NULL); else if (!wdog_auto && wdog_cookie) { shutdownhook_disestablish(wdog_cookie); wdog_cookie = NULL; } break; default: return (EINVAL); } if (wdog_auto && wdog_period > 0) { (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, wdog_period); timeout_add(&wdog_timeout, wdog_period * hz / 2); } else timeout_del(&wdog_timeout); return (error); }
void mb8795_config(struct mb8795_softc *sc, int *media, int nmedia, int defmedia) { struct ifnet *ifp = &sc->sc_ethercom.ec_if; DPRINTF(("%s: mb8795_config()\n",device_xname(sc->sc_dev))); /* Initialize ifnet structure. */ memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); ifp->if_softc = sc; ifp->if_start = mb8795_start; ifp->if_ioctl = mb8795_ioctl; ifp->if_watchdog = mb8795_watchdog; ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS; /* Initialize media goo. */ ifmedia_init(&sc->sc_media, 0, mb8795_mediachange, mb8795_mediastatus); if (media != NULL) { int i; for (i = 0; i < nmedia; i++) ifmedia_add(&sc->sc_media, media[i], 0, NULL); ifmedia_set(&sc->sc_media, defmedia); } else { ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); } /* Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, sc->sc_enaddr); sc->sc_sh = shutdownhook_establish(mb8795_shutdown, sc); if (sc->sc_sh == NULL) panic("mb8795_config: can't establish shutdownhook"); rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); DPRINTF(("%s: leaving mb8795_config()\n",device_xname(sc->sc_dev))); }
static void powsw_attach(device_t parent, device_t self, void *aux) { struct powsw_softc *sc = device_private(self); powsw_desc_t *desc; const char *xname; int unit; int sw; unit = device_unit(self); xname = device_xname(self); desc = &powsw_desc[unit]; memset(sc, 0, sizeof(*sc)); sc->sc_dev = self; sc->sc_mask = desc->mask; sc->sc_prev = -1; powsw_reset_counter(sc); sysmon_task_queue_init(); sc->sc_smpsw.smpsw_name = xname; sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_POWER; if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) panic("can't register with sysmon"); callout_init(&sc->sc_callout, 0); callout_setfunc(&sc->sc_callout, powsw_softintr, sc); if (shutdownhook_establish(powsw_shutdown_check, sc) == NULL) panic("%s: can't establish shutdown hook", xname); if (intio_intr_establish(desc->vector, xname, powsw_intr, sc) < 0) panic("%s: can't establish interrupt", xname); /* Set AER and enable interrupt */ sw = (mfp_get_gpip() & sc->sc_mask); powsw_set_aer(sc, sw ? 0 : 1); mfp_bit_set_ierb(sc->sc_mask); aprint_normal(": %s\n", desc->name); }
static void pdq_tc_attach( struct device * const parent, struct device * const self, void * const aux) { pdq_softc_t * const sc = (pdq_softc_t *) self; struct tc_attach_args * const ta = (struct tc_attach_args *) aux; /* * NOTE: sc_bc is an alias for sc_csrtag and sc_membase is an * alias for sc_csrhandle. sc_iobase is not used in this front-end. */ sc->sc_csrtag = ta->ta_memt; bcopy(sc->sc_dev.dv_xname, sc->sc_if.if_xname, IFNAMSIZ); sc->sc_if.if_flags = 0; sc->sc_if.if_softc = sc; if (bus_space_map(sc->sc_csrtag, ta->ta_addr + PDQ_TC_CSR_OFFSET, PDQ_TC_CSR_SPACE, 0, &sc->sc_csrhandle)) { printf("\n%s: can't map card memory!\n", sc->sc_dev.dv_xname); return; } sc->sc_pdq = pdq_initialize(sc->sc_csrtag, sc->sc_csrhandle, sc->sc_if.if_xname, 0, (void *) sc, PDQ_DEFTA); if (sc->sc_pdq == NULL) { printf("%s: initialization failed\n", sc->sc_dev.dv_xname); return; } bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6); pdq_ifattach(sc, NULL); tc_intr_establish(parent, ta->ta_cookie, TC_IPL_NET, (int (*)(void *)) pdq_interrupt, sc->sc_pdq); sc->sc_ats = shutdownhook_establish((void (*)(void *)) pdq_hwreset, sc->sc_pdq); if (sc->sc_ats == NULL) printf("%s: warning: couldn't establish shutdown hook\n", self->dv_xname); }
void apm_attach(struct device *parent, struct device *self, void *aux) { struct zapm_softc *sc = (struct zapm_softc *)self; pxa2x0_gpio_set_function(GPIO_AC_IN_C3000, GPIO_IN); pxa2x0_gpio_set_function(GPIO_CHRG_CO_C3000, GPIO_IN); pxa2x0_gpio_set_function(GPIO_BATT_COVER_C3000, GPIO_IN); (void)pxa2x0_gpio_intr_establish(GPIO_AC_IN_C3000, IST_EDGE_BOTH, IPL_BIO, zapm_acintr, sc, "apm_ac"); (void)pxa2x0_gpio_intr_establish(GPIO_BATT_COVER_C3000, IST_EDGE_BOTH, IPL_BIO, zapm_bcintr, sc, "apm_bc"); sc->sc_event = APM_NOEVENT; sc->sc.sc_get_event = zapm_get_event; sc->sc.sc_power_info = zapm_power_info; sc->sc.sc_suspend = zapm_suspend; sc->sc.sc_resume = zapm_resume; timeout_set(&sc->sc_poll, &zapm_poll, sc); /* Get initial battery voltage. */ zapm_enable_charging(sc, 0); if (zapm_ac_on()) { /* C3000: discharge 100 ms when AC is on. */ scoop_discharge_battery(1); delay(100000); } sc->sc_batt_volt = zapm_batt_volt(); scoop_discharge_battery(0); pxa2x0_apm_attach_sub(&sc->sc); #if 0 (void)shutdownhook_establish(zapm_shutdown, NULL); #endif cpu_setperf = pxa2x0_setperf; cpu_cpuspeed = pxa2x0_cpuspeed; }
static int lemac_isa_find(lemac_softc_t *sc, const char *xname, struct isa_attach_args *ia, int attach) { bus_addr_t maddr; bus_size_t msiz; int rv = 0, irq; if (ia->ia_nio < 1) return (0); if (ia->ia_niomem < 1) return (0); if (ia->ia_nirq < 1) return (0); if (ISA_DIRECT_CONFIG(ia)) return (0); /* * Disallow wildcarded i/o addresses. */ if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) return 0; /* * Make sure this is a valid LEMAC address. */ if (ia->ia_io[0].ir_addr & (LEMAC_IOSIZE - 1)) return 0; sc->sc_iot = ia->ia_iot; if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, LEMAC_IOSIZE, 0, &sc->sc_ioh)) { if (attach) printf(": can't map i/o space\n"); return 0; } /* * Read the Ethernet address from the EEPROM. * It must start with one of the DEC OUIs and pass the * DEC ethernet checksum test. */ if (lemac_port_check(sc->sc_iot, sc->sc_ioh) == 0) goto outio; /* * Get information about memory space and attempt to map it. */ lemac_info_get(sc->sc_iot, sc->sc_ioh, &maddr, &msiz, &irq); if (ia->ia_iomem[0].ir_addr != ISA_UNKNOWN_IOMEM && ia->ia_iomem[0].ir_addr != maddr) goto outio; if (attach) { if (msiz == 0) { printf(": memory configuration is invalid\n"); goto outio; } sc->sc_memt = ia->ia_memt; if (bus_space_map(ia->ia_memt, maddr, msiz, 0, &sc->sc_memh)) { printf(": can't map mem space\n"); goto outio; } } /* * Double-check IRQ configuration. */ if (ia->ia_irq[0].ir_irq != ISA_UNKNOWN_IRQ && ia->ia_irq[0].ir_irq != irq) printf("%s: overriding IRQ %d to %d\n", xname, ia->ia_irq[0].ir_irq, irq); if (attach) { sc->sc_ats = shutdownhook_establish(lemac_shutdown, sc); if (sc->sc_ats == NULL) { aprint_normal("\n"); aprint_error("%s: warning: can't establish shutdown hook\n", xname); } lemac_ifattach(sc); sc->sc_ih = isa_intr_establish(ia->ia_ic, irq, IST_EDGE, IPL_NET, lemac_intr, sc); } /* * I guess we've found one. */ rv = 1; ia->ia_nio = 1; ia->ia_io[0].ir_size = LEMAC_IOSIZE; ia->ia_niomem = 1; ia->ia_iomem[0].ir_addr = maddr; ia->ia_iomem[0].ir_size = msiz; ia->ia_nirq = 1; ia->ia_irq[0].ir_irq = irq; ia->ia_ndrq = 0; outio: if (rv == 0 || !attach) bus_space_unmap(sc->sc_iot, sc->sc_ioh, LEMAC_IOSIZE); return rv; }
void rapide_attach(device_t parent, device_t self, void *aux) { struct rapide_softc *sc = device_private(self); struct podule_attach_args *pa = (void *)aux; bus_space_tag_t iot; bus_space_handle_t ctlioh; u_int iobase; int channel, i; struct rapide_channel *rcp; struct ata_channel *cp; struct wdc_regs *wdr; irqhandler_t *ihp; /* Note the podule number and validate */ if (pa->pa_podule_number == -1) panic("Podule has disappeared !"); sc->sc_wdcdev.sc_atac.atac_dev = self; sc->sc_podule_number = pa->pa_podule_number; sc->sc_podule = pa->pa_podule; podules[sc->sc_podule_number].attached = 1; sc->sc_wdcdev.regs = sc->sc_wdc_regs; set_easi_cycle_type(sc->sc_podule_number, EASI_CYCLE_TYPE_C); /* * Duplicate the podule bus space tag and provide alternative * bus_space_read_multi_4() and bus_space_write_multi_4() * functions. */ rapide_bs_tag = *pa->pa_iot; rapide_bs_tag.bs_rm_4 = rapide_bs_rm_4; rapide_bs_tag.bs_wm_4 = rapide_bs_wm_4; sc->sc_ctliot = iot = &rapide_bs_tag; if (bus_space_map(iot, pa->pa_podule->easi_base + CONTROL_REGISTERS_OFFSET, CONTROL_REGISTER_SPACE, 0, &ctlioh)) panic("%s: Cannot map control registers", device_xname(self)); sc->sc_ctlioh = ctlioh; sc->sc_version = bus_space_read_1(iot, ctlioh, VERSION_REGISTER_OFFSET) & VERSION_REGISTER_MASK; /* bus_space_unmap(iot, ctl_ioh, CONTROL_REGISTER_SPACE);*/ aprint_normal(": Issue %d\n", sc->sc_version + 1); if (sc->sc_version != VERSION_2_ID) return; if (shutdownhook_establish(rapide_shutdown, (void *)sc) == NULL) panic("%s: Cannot install shutdown handler", device_xname(self)); /* Set the interrupt info for this podule */ sc->sc_podule->irq_addr = pa->pa_podule->easi_base + CONTROL_REGISTERS_OFFSET + IRQ_REQUEST_REGISTER_BYTE_OFFSET; sc->sc_podule->irq_mask = IRQ_MASK; iobase = pa->pa_podule->easi_base; /* Fill in wdc and channel infos */ sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA32; sc->sc_wdcdev.sc_atac.atac_pio_cap = 0; sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = 2; sc->sc_wdcdev.wdc_maxdrives = 2; for (channel = 0 ; channel < 2; channel++) { rcp = &sc->rapide_channels[channel]; sc->sc_chanarray[channel] = &rcp->rc_channel; cp = &rcp->rc_channel; wdr = &sc->sc_wdc_regs[channel]; cp->ch_channel = channel; cp->ch_atac = &sc->sc_wdcdev.sc_atac; cp->ch_queue = &rcp->rc_chqueue; wdr->cmd_iot = iot; wdr->ctl_iot = iot; wdr->data32iot = iot; if (bus_space_map(iot, iobase + rapide_info[channel].registers, DRIVE_REGISTERS_SPACE, 0, &wdr->cmd_baseioh)) continue; for (i = 0; i < WDC_NREG; i++) { if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh, i, i == 0 ? 4 : 1, &wdr->cmd_iohs[i]) != 0) { bus_space_unmap(iot, wdr->cmd_baseioh, DRIVE_REGISTERS_SPACE); continue; } } wdc_init_shadow_regs(cp); if (bus_space_map(iot, iobase + rapide_info[channel].aux_register, 4, 0, &wdr->ctl_ioh)) { bus_space_unmap(iot, wdr->cmd_baseioh, DRIVE_REGISTERS_SPACE); continue; } if (bus_space_map(iot, iobase + rapide_info[channel].data_register, 4, 0, &wdr->data32ioh)) { bus_space_unmap(iot, wdr->cmd_baseioh, DRIVE_REGISTERS_SPACE); bus_space_unmap(iot, wdr->ctl_ioh, 4); continue; } /* Disable interrupts and clear any pending interrupts */ rcp->rc_irqmask = rapide_info[channel].irq_mask; sc->sc_intr_enable_mask &= ~rcp->rc_irqmask; bus_space_write_1(iot, sc->sc_ctlioh, IRQ_MASK_REGISTER_OFFSET, sc->sc_intr_enable_mask); /* XXX - Issue 1 cards will need to clear any pending interrupts */ ihp = &rcp->rc_ih; ihp->ih_func = rapide_intr; ihp->ih_arg = rcp; ihp->ih_level = IPL_BIO; ihp->ih_name = "rapide"; ihp->ih_maskaddr = pa->pa_podule->irq_addr; ihp->ih_maskbits = rcp->rc_irqmask; if (irq_claim(sc->sc_podule->interrupt, ihp)) panic("%s: Cannot claim interrupt %d", device_xname(self), sc->sc_podule->interrupt); /* clear any pending interrupts and enable interrupts */ sc->sc_intr_enable_mask |= rcp->rc_irqmask; bus_space_write_1(iot, sc->sc_ctlioh, IRQ_MASK_REGISTER_OFFSET, sc->sc_intr_enable_mask); /* XXX - Issue 1 cards will need to clear any pending interrupts */ wdcattach(cp); } }
static void ll_tft_attach(struct device *parent, struct device *self, void *aux) { struct xcvbus_attach_args *vaa = aux; struct ll_dmac *tx = vaa->vaa_tx_dmac; struct ll_tft_softc *lsc = (struct ll_tft_softc *)self; struct tft_softc *sc = &lsc->lsc_sc; int nseg, error; KASSERT(tx); lsc->lsc_dma_iot = tx->dmac_iot; lsc->lsc_dmat = vaa->vaa_dmat; sc->sc_iot = vaa->vaa_iot; printf(": LL_TFT\n"); if ((error = bus_space_map(sc->sc_iot, vaa->vaa_addr, TFT_SIZE, 0, &sc->sc_ioh)) != 0) { printf("%s: could not map device registers\n", device_xname(self)); goto fail_0; } if ((error = bus_space_map(lsc->lsc_dma_iot, tx->dmac_ctrl_addr, CDMAC_CTRL_SIZE, 0, &lsc->lsc_dma_ioh)) != 0) { printf("%s: could not map dmac registers\n", device_xname(self)); goto fail_1; } /* Fill in resolution, depth, size. */ tft_mode(&sc->sc_dev); /* Allocate and map framebuffer control data. */ if ((error = bus_dmamem_alloc(lsc->lsc_dmat, sizeof(struct ll_tft_control) + sc->sc_size, 8, 0, &lsc->lsc_seg, 1, &nseg, 0)) != 0) { printf("%s: could not allocate framebuffer\n", device_xname(self)); goto fail_2; } if ((error = bus_dmamem_map(lsc->lsc_dmat, &lsc->lsc_seg, nseg, sizeof(struct ll_tft_control) + sc->sc_size, (void **)&lsc->lsc_cd, BUS_DMA_COHERENT)) != 0) { printf("%s: could not map framebuffer\n", device_xname(self)); goto fail_3; } if ((error = bus_dmamap_create(lsc->lsc_dmat, sizeof(struct ll_tft_control) + sc->sc_size, 1, sizeof(struct ll_tft_control) + sc->sc_size, 0, 0, &lsc->lsc_dmap)) != 0) { printf("%s: could not create framebuffer DMA map\n", device_xname(self)); goto fail_4; } if ((error = bus_dmamap_load(lsc->lsc_dmat, lsc->lsc_dmap, lsc->lsc_cd, sizeof(struct ll_tft_control) + sc->sc_size, NULL, 0)) != 0) { printf("%s: could not load framebuffer DMA map\n", device_xname(self)); goto fail_5; } /* Clear screen, setup descriptor. */ memset(lsc->lsc_cd, 0x00, sizeof(struct ll_tft_control)); sc->sc_image = lsc->lsc_cd->cd_img; lsc->lsc_cd->cd_dsc.desc_next = lsc->lsc_dmap->dm_segs[0].ds_addr; lsc->lsc_cd->cd_dsc.desc_addr = lsc->lsc_dmap->dm_segs[0].ds_addr + offsetof(struct ll_tft_control, cd_img); lsc->lsc_cd->cd_dsc.desc_size = sc->sc_size; lsc->lsc_cd->cd_dsc.desc_stat = CDMAC_STAT_SOP; bus_dmamap_sync(lsc->lsc_dmat, lsc->lsc_dmap, 0, sizeof(struct ll_tft_control) + sc->sc_size, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); sc->sc_sdhook = shutdownhook_establish(ll_tft_shutdown, sc); if (sc->sc_sdhook == NULL) printf("%s: WARNING: unable to establish shutdown hook\n", device_xname(self)); tft_attach(self, &ll_tft_accessops); printf("%s: video memory pa 0x%08x\n", device_xname(self), (uint32_t)lsc->lsc_cd->cd_dsc.desc_addr); /* Timing sensitive... */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, TFT_CTRL, CTRL_RESET); bus_space_write_4(sc->sc_iot, sc->sc_ioh, TFT_CTRL, CTRL_ENABLE); bus_space_write_4(lsc->lsc_dma_iot, lsc->lsc_dma_ioh, CDMAC_CURDESC, lsc->lsc_dmap->dm_segs[0].ds_addr); return ; fail_5: bus_dmamap_destroy(lsc->lsc_dmat, lsc->lsc_dmap); fail_4: bus_dmamem_unmap(lsc->lsc_dmat, (void *)lsc->lsc_cd, sizeof(struct ll_tft_control) + sc->sc_size); fail_3: bus_dmamem_free(lsc->lsc_dmat, &lsc->lsc_seg, nseg); fail_2: bus_space_unmap(lsc->lsc_dma_iot, lsc->lsc_dma_ioh, CDMAC_CTRL_SIZE); fail_1: bus_space_unmap(sc->sc_iot, sc->sc_ioh, TFT_SIZE); fail_0: printf("%s: error %d\n", device_xname(self), error); }
/* * Initialise our interface to the controller. */ int cac_init(struct cac_softc *sc, int startfw) { struct scsibus_attach_args saa; struct cac_controller_info cinfo; int error, rseg, size, i; bus_dma_segment_t seg[1]; struct cac_ccb *ccb; SIMPLEQ_INIT(&sc->sc_ccb_free); SIMPLEQ_INIT(&sc->sc_ccb_queue); size = sizeof(struct cac_ccb) * CAC_MAX_CCBS; if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { printf("%s: unable to allocate CCBs, error = %d\n", sc->sc_dv.dv_xname, error); return (-1); } if ((error = bus_dmamem_map(sc->sc_dmat, seg, rseg, size, &sc->sc_ccbs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { printf("%s: unable to map CCBs, error = %d\n", sc->sc_dv.dv_xname, error); return (-1); } if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { printf("%s: unable to create CCB DMA map, error = %d\n", sc->sc_dv.dv_xname, error); return (-1); } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ccbs, size, NULL, BUS_DMA_NOWAIT)) != 0) { printf("%s: unable to load CCB DMA map, error = %d\n", sc->sc_dv.dv_xname, error); return (-1); } sc->sc_ccbs_paddr = sc->sc_dmamap->dm_segs[0].ds_addr; memset(sc->sc_ccbs, 0, size); ccb = (struct cac_ccb *)sc->sc_ccbs; for (i = 0; i < CAC_MAX_CCBS; i++, ccb++) { /* Create the DMA map for this CCB's data */ error = bus_dmamap_create(sc->sc_dmat, CAC_MAX_XFER, CAC_SG_SIZE, CAC_MAX_XFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap_xfer); if (error) { printf("%s: can't create ccb dmamap (%d)\n", sc->sc_dv.dv_xname, error); break; } ccb->ccb_paddr = sc->sc_ccbs_paddr + i * sizeof(struct cac_ccb); SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_chain); } /* Start firmware background tasks, if needed. */ if (startfw) { if (cac_cmd(sc, CAC_CMD_START_FIRMWARE, &cinfo, sizeof(cinfo), 0, 0, CAC_CCB_DATA_IN, NULL)) { printf("%s: CAC_CMD_START_FIRMWARE failed\n", sc->sc_dv.dv_xname); return (-1); } } if (cac_cmd(sc, CAC_CMD_GET_CTRL_INFO, &cinfo, sizeof(cinfo), 0, 0, CAC_CCB_DATA_IN, NULL)) { printf("%s: CAC_CMD_GET_CTRL_INFO failed\n", sc->sc_dv.dv_xname); return (-1); } if (!cinfo.num_drvs) { printf("%s: no volumes defined\n", sc->sc_dv.dv_xname); return (-1); } sc->sc_nunits = cinfo.num_drvs; sc->sc_dinfos = malloc(cinfo.num_drvs * sizeof(struct cac_drive_info), M_DEVBUF, M_NOWAIT | M_ZERO); if (sc->sc_dinfos == NULL) { printf("%s: cannot allocate memory for drive_info\n", sc->sc_dv.dv_xname); return (-1); } sc->sc_link.adapter_softc = sc; sc->sc_link.adapter = &cac_switch; sc->sc_link.adapter_target = cinfo.num_drvs; sc->sc_link.adapter_buswidth = cinfo.num_drvs; sc->sc_link.device = &cac_dev; sc->sc_link.openings = CAC_MAX_CCBS / sc->sc_nunits; if (sc->sc_link.openings < 4 ) sc->sc_link.openings = 4; bzero(&saa, sizeof(saa)); saa.saa_sc_link = &sc->sc_link; config_found(&sc->sc_dv, &saa, scsiprint); /* Set our `shutdownhook' before we start any device activity. */ if (cac_sdh == NULL) cac_sdh = shutdownhook_establish(cac_shutdown, NULL); (*sc->sc_cl->cl_intr_enable)(sc, 1); return (0); }
void mec_attach(struct device *parent, struct device *self, void *aux) { struct mec_softc *sc = (void *)self; struct confargs *ca = aux; struct ifnet *ifp = &sc->sc_ac.ac_if; uint32_t command; struct mii_softc *child; bus_dma_segment_t seg; int i, err, rseg; sc->sc_st = ca->ca_iot; if (bus_space_map(sc->sc_st, ca->ca_baseaddr, MEC_NREGS, 0, &sc->sc_sh) != 0) { printf(": can't map i/o space\n"); return; } /* Set up DMA structures. */ sc->sc_dmat = ca->ca_dmat; /* * Allocate the control data structures, and create and load the * DMA map for it. */ if ((err = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct mec_control_data), MEC_CONTROL_DATA_ALIGN, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { printf(": unable to allocate control data, error = %d\n", err); goto fail_0; } /* * XXX needs re-think... * control data structures contain whole RX data buffer, so * BUS_DMA_COHERENT (which disables cache) may cause some performance * issue on copying data from the RX buffer to mbuf on normal memory, * though we have to make sure all bus_dmamap_sync(9) ops are called * properly in that case. */ if ((err = bus_dmamem_map(sc->sc_dmat, &seg, rseg, sizeof(struct mec_control_data), (caddr_t *)&sc->sc_control_data, /*BUS_DMA_COHERENT*/ 0)) != 0) { printf(": unable to map control data, error = %d\n", err); goto fail_1; } memset(sc->sc_control_data, 0, sizeof(struct mec_control_data)); if ((err = bus_dmamap_create(sc->sc_dmat, sizeof(struct mec_control_data), 1, sizeof(struct mec_control_data), 0, 0, &sc->sc_cddmamap)) != 0) { printf(": unable to create control data DMA map, error = %d\n", err); goto fail_2; } if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, sc->sc_control_data, sizeof(struct mec_control_data), NULL, BUS_DMA_NOWAIT)) != 0) { printf(": unable to load control data DMA map, error = %d\n", err); goto fail_3; } /* Create TX buffer DMA maps. */ for (i = 0; i < MEC_NTXDESC; i++) { if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->sc_txsoft[i].txs_dmamap)) != 0) { printf(": unable to create tx DMA map %d, error = %d\n", i, err); goto fail_4; } } timeout_set(&sc->sc_tick_ch, mec_tick, sc); /* Use the Ethernet address from the ARCBIOS. */ enaddr_aton(bios_enaddr, sc->sc_ac.ac_enaddr); /* Reset device. */ mec_reset(sc); command = bus_space_read_8(sc->sc_st, sc->sc_sh, MEC_MAC_CONTROL); printf(": MAC-110 rev %d, address %s\n", (command & MEC_MAC_REVISION) >> MEC_MAC_REVISION_SHIFT, ether_sprintf(sc->sc_ac.ac_enaddr)); /* Done, now attach everything. */ sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = mec_mii_readreg; sc->sc_mii.mii_writereg = mec_mii_writereg; sc->sc_mii.mii_statchg = mec_statchg; /* Set up PHY properties. */ ifmedia_init(&sc->sc_mii.mii_media, 0, mec_mediachange, mec_mediastatus); mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); child = LIST_FIRST(&sc->sc_mii.mii_phys); if (child == NULL) { /* No PHY attached. */ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL); } else { ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO); sc->sc_phyaddr = child->mii_phy; } bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = mec_ioctl; ifp->if_start = mec_start; ifp->if_watchdog = mec_watchdog; IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); IFQ_SET_MAXLEN(&ifp->if_snd, MEC_NTXDESC - 1); ether_ifattach(ifp); /* Establish interrupt handler. */ macebus_intr_establish(NULL, ca->ca_intr, IST_EDGE, IPL_NET, mec_intr, sc, sc->sc_dev.dv_xname); /* Set hook to stop interface on shutdown. */ sc->sc_sdhook = shutdownhook_establish(mec_shutdown, sc); return; /* * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall though. */ fail_4: for (i = 0; i < MEC_NTXDESC; i++) { if (sc->sc_txsoft[i].txs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmamap); } bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); fail_3: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); fail_2: bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data, sizeof(struct mec_control_data)); fail_1: bus_dmamem_free(sc->sc_dmat, &seg, rseg); fail_0: return; }
/* * sonic_attach: * * Attach a SONIC interface to the system. */ void sonic_attach(struct sonic_softc *sc, const uint8_t *enaddr) { struct ifnet *ifp = &sc->sc_ethercom.ec_if; int i, rseg, error; bus_dma_segment_t seg; size_t cdatasize; uint8_t *nullbuf; /* * Allocate the control data structures, and create and load the * DMA map for it. */ if (sc->sc_32bit) cdatasize = sizeof(struct sonic_control_data32); else cdatasize = sizeof(struct sonic_control_data16); if ((error = bus_dmamem_alloc(sc->sc_dmat, cdatasize + ETHER_PAD_LEN, PAGE_SIZE, (64 * 1024), &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "unable to allocate control data, error = %d\n", error); goto fail_0; } if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, cdatasize + ETHER_PAD_LEN, (void **) &sc->sc_cdata16, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { aprint_error_dev(sc->sc_dev, "unable to map control data, error = %d\n", error); goto fail_1; } nullbuf = (uint8_t *)sc->sc_cdata16 + cdatasize; memset(nullbuf, 0, ETHER_PAD_LEN); if ((error = bus_dmamap_create(sc->sc_dmat, cdatasize, 1, cdatasize, 0, BUS_DMA_NOWAIT, &sc->sc_cddmamap)) != 0) { aprint_error_dev(sc->sc_dev, "unable to create control data DMA map, error = %d\n", error); goto fail_2; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, sc->sc_cdata16, cdatasize, NULL, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "unable to load control data DMA map, error = %d\n", error); goto fail_3; } /* * Create the transmit buffer DMA maps. */ for (i = 0; i < SONIC_NTXDESC; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, SONIC_NTXFRAGS, MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->sc_txsoft[i].ds_dmamap)) != 0) { aprint_error_dev(sc->sc_dev, "unable to create tx DMA map %d, error = %d\n", i, error); goto fail_4; } } /* * Create the receive buffer DMA maps. */ for (i = 0; i < SONIC_NRXDESC; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->sc_rxsoft[i].ds_dmamap)) != 0) { aprint_error_dev(sc->sc_dev, "unable to create rx DMA map %d, error = %d\n", i, error); goto fail_5; } sc->sc_rxsoft[i].ds_mbuf = NULL; } /* * create and map the pad buffer */ if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1, ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT, &sc->sc_nulldmamap)) != 0) { aprint_error_dev(sc->sc_dev, "unable to create pad buffer DMA map, error = %d\n", error); goto fail_5; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap, nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "unable to load pad buffer DMA map, error = %d\n", error); goto fail_6; } bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN, BUS_DMASYNC_PREWRITE); /* * Reset the chip to a known state. */ sonic_reset(sc); aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n", ether_sprintf(enaddr)); strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = sonic_ioctl; ifp->if_start = sonic_start; ifp->if_watchdog = sonic_watchdog; ifp->if_init = sonic_init; ifp->if_stop = sonic_stop; IFQ_SET_READY(&ifp->if_snd); /* * We can support 802.1Q VLAN-sized frames. */ sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; /* * Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, enaddr); /* * Make sure the interface is shutdown during reboot. */ sc->sc_sdhook = shutdownhook_establish(sonic_shutdown, sc); if (sc->sc_sdhook == NULL) aprint_error_dev(sc->sc_dev, "WARNING: unable to establish shutdown hook\n"); return; /* * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall through. */ fail_6: bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap); fail_5: for (i = 0; i < SONIC_NRXDESC; i++) { if (sc->sc_rxsoft[i].ds_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].ds_dmamap); } fail_4: for (i = 0; i < SONIC_NTXDESC; i++) { if (sc->sc_txsoft[i].ds_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].ds_dmamap); } bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); fail_3: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); fail_2: bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_cdata16, cdatasize); fail_1: bus_dmamem_free(sc->sc_dmat, &seg, rseg); fail_0: return; }
/* * Interface exists: make available by filling in network interface * record. System will initialize the interface when it is ready * to accept packets. We get the ethernet address here. */ void deattach(struct device *parent, struct device *self, void *aux) { struct uba_attach_args *ua = aux; struct de_softc *sc = (struct de_softc *)self; struct ifnet *ifp = &sc->sc_if; u_int8_t myaddr[ETHER_ADDR_LEN]; int csr1, error; char *c; sc->sc_iot = ua->ua_iot; sc->sc_ioh = ua->ua_ioh; sc->sc_dmat = ua->ua_dmat; /* * What kind of a board is this? * The error bits 4-6 in pcsr1 are a device id as long as * the high byte is zero. */ csr1 = DE_RCSR(DE_PCSR1); if (csr1 & 0xff60) c = "broken"; else if (csr1 & 0x10) c = "delua"; else c = "deuna"; /* * Reset the board and temporarily map * the pcbb buffer onto the Unibus. */ DE_WCSR(DE_PCSR0, 0); /* reset INTE */ DELAY(100); DE_WCSR(DE_PCSR0, PCSR0_RSET); dewait(sc, "reset"); sc->sc_ui.ui_size = sizeof(struct de_cdata); if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0))) return printf(": failed ubmemalloc(), error = %d\n", error); sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr; /* * Tell the DEUNA about our PCB */ DE_WCSR(DE_PCSR2, LOWORD(sc->sc_ui.ui_baddr)); DE_WCSR(DE_PCSR3, HIWORD(sc->sc_ui.ui_baddr)); DE_WLOW(CMD_GETPCBB); dewait(sc, "pcbb"); sc->sc_dedata->dc_pcbb.pcbb0 = FC_RDPHYAD; DE_WLOW(CMD_GETCMD); dewait(sc, "read addr "); bcopy((caddr_t)&sc->sc_dedata->dc_pcbb.pcbb2, myaddr, sizeof (myaddr)); printf(": %s, address %s\n", c, ether_sprintf(myaddr)); uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc, &sc->sc_intrcnt); uba_reset_establish(dereset, &sc->sc_dev); evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt, sc->sc_dev.dv_xname, "intr"); strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI; ifp->if_ioctl = deioctl; ifp->if_start = destart; ifp->if_init = deinit; ifp->if_stop = destop; IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); ether_ifattach(ifp, myaddr); ubmemfree((struct uba_softc *)parent, &sc->sc_ui); sc->sc_sh = shutdownhook_establish(deshutdown, sc); }
static void ste_attach(device_t parent, device_t self, void *aux) { struct ste_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct ifnet *ifp = &sc->sc_ethercom.ec_if; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr = NULL; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; bus_dma_segment_t seg; int ioh_valid, memh_valid; int i, rseg, error; const struct ste_product *sp; uint8_t enaddr[ETHER_ADDR_LEN]; uint16_t myea[ETHER_ADDR_LEN / 2]; callout_init(&sc->sc_tick_ch, 0); sp = ste_lookup(pa); if (sp == NULL) { printf("\n"); panic("ste_attach: impossible"); } printf(": %s\n", sp->ste_name); /* * Map the device. */ ioh_valid = (pci_mapreg_map(pa, STE_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) == 0); memh_valid = (pci_mapreg_map(pa, STE_PCI_MMBA, PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, NULL, NULL) == 0); if (memh_valid) { sc->sc_st = memt; sc->sc_sh = memh; } else if (ioh_valid) { sc->sc_st = iot; sc->sc_sh = ioh; } else { aprint_error_dev(&sc->sc_dev, "unable to map device registers\n"); return; } sc->sc_dmat = pa->pa_dmat; /* Enable bus mastering. */ 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); /* power up chip */ if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self, NULL)) && error != EOPNOTSUPP) { aprint_error_dev(&sc->sc_dev, "cannot activate %d\n", error); return; } /* * Map and establish our interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(&sc->sc_dev, "unable to map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ste_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(&sc->sc_dev, "unable to establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf("%s: interrupting at %s\n", device_xname(&sc->sc_dev), intrstr); /* * Allocate the control data structures, and create and load the * DMA map for it. */ if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct ste_control_data), PAGE_SIZE, 0, &seg, 1, &rseg, 0)) != 0) { aprint_error_dev(&sc->sc_dev, "unable to allocate control data, error = %d\n", error); goto fail_0; } if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, sizeof(struct ste_control_data), (void **)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) { aprint_error_dev(&sc->sc_dev, "unable to map control data, error = %d\n", error); goto fail_1; } if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct ste_control_data), 1, sizeof(struct ste_control_data), 0, 0, &sc->sc_cddmamap)) != 0) { aprint_error_dev(&sc->sc_dev, "unable to create control data DMA map, " "error = %d\n", error); goto fail_2; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, sc->sc_control_data, sizeof(struct ste_control_data), NULL, 0)) != 0) { aprint_error_dev(&sc->sc_dev, "unable to load control data DMA map, error = %d\n", error); goto fail_3; } /* * Create the transmit buffer DMA maps. */ for (i = 0; i < STE_NTXDESC; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, STE_NTXFRAGS, MCLBYTES, 0, 0, &sc->sc_txsoft[i].ds_dmamap)) != 0) { aprint_error_dev(&sc->sc_dev, "unable to create tx DMA map %d, " "error = %d\n", i, error); goto fail_4; } } /* * Create the receive buffer DMA maps. */ for (i = 0; i < STE_NRXDESC; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->sc_rxsoft[i].ds_dmamap)) != 0) { aprint_error_dev(&sc->sc_dev, "unable to create rx DMA map %d, " "error = %d\n", i, error); goto fail_5; } sc->sc_rxsoft[i].ds_mbuf = NULL; } /* * Reset the chip to a known state. */ ste_reset(sc, AC_GlobalReset | AC_RxReset | AC_TxReset | AC_DMA | AC_FIFO | AC_Network | AC_Host | AC_AutoInit | AC_RstOut); /* * Read the Ethernet address from the EEPROM. */ for (i = 0; i < 3; i++) { ste_read_eeprom(sc, STE_EEPROM_StationAddress0 + i, &myea[i]); myea[i] = le16toh(myea[i]); } memcpy(enaddr, myea, sizeof(enaddr)); printf("%s: Ethernet address %s\n", device_xname(&sc->sc_dev), ether_sprintf(enaddr)); /* * Initialize our media structures and probe the MII. */ sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = ste_mii_readreg; sc->sc_mii.mii_writereg = ste_mii_writereg; sc->sc_mii.mii_statchg = ste_mii_statchg; sc->sc_ethercom.ec_mii = &sc->sc_mii; ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange, ether_mediastatus); mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); } else ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); ifp = &sc->sc_ethercom.ec_if; strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = ste_ioctl; ifp->if_start = ste_start; ifp->if_watchdog = ste_watchdog; ifp->if_init = ste_init; ifp->if_stop = ste_stop; IFQ_SET_READY(&ifp->if_snd); /* * Default the transmit threshold to 128 bytes. */ sc->sc_txthresh = 128; /* * Disable MWI if the PCI layer tells us to. */ sc->sc_DMACtrl = 0; if ((pa->pa_flags & PCI_FLAGS_MWI_OKAY) == 0) sc->sc_DMACtrl |= DC_MWIDisable; /* * We can support 802.1Q VLAN-sized frames. */ sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; /* * Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, enaddr); /* * Make sure the interface is shutdown during reboot. */ sc->sc_sdhook = shutdownhook_establish(ste_shutdown, sc); if (sc->sc_sdhook == NULL) printf("%s: WARNING: unable to establish shutdown hook\n", device_xname(&sc->sc_dev)); return; /* * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall through. */ fail_5: for (i = 0; i < STE_NRXDESC; i++) { if (sc->sc_rxsoft[i].ds_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].ds_dmamap); } fail_4: for (i = 0; i < STE_NTXDESC; i++) { if (sc->sc_txsoft[i].ds_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].ds_dmamap); } bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); fail_3: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); fail_2: bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, sizeof(struct ste_control_data)); fail_1: bus_dmamem_free(sc->sc_dmat, &seg, rseg); fail_0: return; }
/* * Interface exists: make available by filling in network interface * record. System will initialize the interface when it is ready * to accept packets. */ static void niattach(device_t parent, device_t self, void *aux) { struct bi_attach_args *ba = aux; struct ni_softc *sc = device_private(self); struct ifnet *ifp = (struct ifnet *)&sc->sc_if; struct ni_msg *msg; struct ni_ptdb *ptdb; void *va; int i, j, s, res; u_short type; sc->sc_dev = self; type = bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE); printf(": DEBN%c\n", type == BIDT_DEBNA ? 'A' : type == BIDT_DEBNT ? 'T' : 'K'); sc->sc_iot = ba->ba_iot; sc->sc_ioh = ba->ba_ioh; sc->sc_dmat = ba->ba_dmat; bi_intr_establish(ba->ba_icookie, ba->ba_ivec, niintr, sc, &sc->sc_intrcnt); evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, device_xname(self), "intr"); ni_getpgs(sc, sizeof(struct ni_gvppqb), (void **)&sc->sc_gvppqb, (paddr_t *)&sc->sc_pgvppqb); ni_getpgs(sc, sizeof(struct ni_fqb), (void **)&sc->sc_fqb, 0); ni_getpgs(sc, NBDESCS * sizeof(struct ni_bbd), (void **)&sc->sc_bbd, 0); /* * Zero the newly allocated memory. */ nipqb->np_veclvl = (ba->ba_ivec << 2) + 2; nipqb->np_node = ba->ba_intcpu; nipqb->np_vpqb = (u_int32_t)gvp; #ifdef __vax__ nipqb->np_spt = nipqb->np_gpt = mfpr(PR_SBR); nipqb->np_sptlen = nipqb->np_gptlen = mfpr(PR_SLR); #else #error Must fix support for non-vax. #endif nipqb->np_bvplvl = 1; nipqb->np_vfqb = (u_int32_t)fqb; nipqb->np_vbdt = (u_int32_t)bbd; nipqb->np_nbdr = NBDESCS; /* Free queue block */ nipqb->np_freeq = NQUEUES; fqb->nf_mlen = PKTHDR+MSGADD; fqb->nf_dlen = PKTHDR+TXADD; fqb->nf_rlen = PKTHDR+RXADD; strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_start = nistart; ifp->if_ioctl = niioctl; ifp->if_watchdog = nitimeout; IFQ_SET_READY(&ifp->if_snd); /* * Start init sequence. */ /* Reset the node */ NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST); DELAY(500000); i = 20; while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i) DELAY(500000); if (i == 0) { printf("%s: BROKE bit set after reset\n", device_xname(self)); return; } /* Check state */ if (failtest(sc, NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state")) return; /* Clear owner bits */ NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN); NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN); /* kick off init */ NI_WREG(NI_PCR, (u_int32_t)sc->sc_pgvppqb | PCR_INIT | PCR_OWN); while (NI_RREG(NI_PCR) & PCR_OWN) DELAY(100000); /* Check state */ if (failtest(sc, NI_PSR, PSR_INITED, PSR_INITED, "failed initialize")) return; NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN); WAITREG(NI_PCR, PCR_OWN); NI_WREG(NI_PCR, PCR_OWN|PCR_ENABLE); WAITREG(NI_PCR, PCR_OWN); WAITREG(NI_PSR, PSR_OWN); /* Check state */ if (failtest(sc, NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable")) return; NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN); /* * The message queue packets must be located on the beginning * of a page. A VAX page is 512 bytes, but it clusters 8 pages. * This knowledge is used here when allocating pages. * !!! How should this be done on MIPS and Alpha??? !!! */ #if NBPG < 4096 #error pagesize too small #endif s = splvm(); /* Set up message free queue */ ni_getpgs(sc, NMSGBUF * 512, &va, 0); for (i = 0; i < NMSGBUF; i++) { msg = (void *)((char *)va + i * 512); res = INSQTI(msg, &fqb->nf_mforw); } WAITREG(NI_PCR, PCR_OWN); NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN); WAITREG(NI_PCR, PCR_OWN); /* Set up xmit queue */ ni_getpgs(sc, NTXBUF * 512, &va, 0); for (i = 0; i < NTXBUF; i++) { struct ni_dg *data; data = (void *)((char *)va + i * 512); data->nd_status = 0; data->nd_len = TXADD; data->nd_ptdbidx = 1; data->nd_opcode = BVP_DGRAM; for (j = 0; j < NTXFRAGS; j++) { data->bufs[j]._offset = 0; data->bufs[j]._key = 1; bbd[i * NTXFRAGS + j].nb_key = 1; bbd[i * NTXFRAGS + j].nb_status = 0; data->bufs[j]._index = i * NTXFRAGS + j; } res = INSQTI(data, &fqb->nf_dforw); } WAITREG(NI_PCR, PCR_OWN); NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN); WAITREG(NI_PCR, PCR_OWN); /* recv buffers */ ni_getpgs(sc, NRXBUF * 512, &va, 0); for (i = 0; i < NRXBUF; i++) { struct ni_dg *data; int idx; data = (void *)((char *)va + i * 512); data->nd_len = RXADD; data->nd_opcode = BVP_DGRAMRX; data->nd_ptdbidx = 2; data->bufs[0]._key = 1; idx = NTXBUF * NTXFRAGS + i; if (ni_add_rxbuf(sc, data, idx)) panic("niattach: ni_add_rxbuf: out of mbufs"); res = INSQTI(data, &fqb->nf_rforw); } WAITREG(NI_PCR, PCR_OWN); NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN); WAITREG(NI_PCR, PCR_OWN); splx(s); /* Set initial parameters */ msg = REMQHI(&fqb->nf_mforw); msg->nm_opcode = BVP_MSG; msg->nm_status = 0; msg->nm_len = sizeof(struct ni_param) + 6; msg->nm_opcode2 = NI_WPARAM; ((struct ni_param *)&msg->nm_text[0])->np_flags = NP_PAD; endwait = retry = 0; res = INSQTI(msg, &gvp->nc_forw0); retry: WAITREG(NI_PCR, PCR_OWN); NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); WAITREG(NI_PCR, PCR_OWN); i = 1000; while (endwait == 0 && --i) DELAY(10000); if (endwait == 0) { if (++retry < 3) goto retry; printf("%s: no response to set params\n", device_xname(self)); return; } /* Clear counters */ msg = REMQHI(&fqb->nf_mforw); msg->nm_opcode = BVP_MSG; msg->nm_status = 0; msg->nm_len = sizeof(struct ni_param) + 6; msg->nm_opcode2 = NI_RCCNTR; res = INSQTI(msg, &gvp->nc_forw0); WAITREG(NI_PCR, PCR_OWN); NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); WAITREG(NI_PCR, PCR_OWN); /* Enable transmit logic */ msg = REMQHI(&fqb->nf_mforw); msg->nm_opcode = BVP_MSG; msg->nm_status = 0; msg->nm_len = 18; msg->nm_opcode2 = NI_STPTDB; ptdb = (struct ni_ptdb *)&msg->nm_text[0]; memset(ptdb, 0, sizeof(struct ni_ptdb)); ptdb->np_index = 1; ptdb->np_fque = 1; res = INSQTI(msg, &gvp->nc_forw0); WAITREG(NI_PCR, PCR_OWN); NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN); WAITREG(NI_PCR, PCR_OWN); /* Wait for everything to finish */ WAITREG(NI_PSR, PSR_OWN); printf("%s: hardware address %s\n", device_xname(self), ether_sprintf(sc->sc_enaddr)); /* * Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, sc->sc_enaddr); if (shutdownhook_establish(ni_shutdown, sc) == 0) aprint_error_dev(self, "WARNING: unable to establish shutdown hook\n"); }
void sabtty_attach(struct device *parent, struct device *self, void *aux) { struct sabtty_softc *sc = (struct sabtty_softc *)self; struct sabtty_attach_args *sa = aux; int r; int maj; int is_kgdb = 0; #ifdef KGDB is_kgdb = sab_kgdb_check(sc); #endif if (!is_kgdb) { sc->sc_tty = ttymalloc(); if (sc->sc_tty == NULL) { aprint_normal(": failed to allocate tty\n"); return; } tty_attach(sc->sc_tty); sc->sc_tty->t_oproc = sabtty_start; sc->sc_tty->t_param = sabtty_param; } sc->sc_parent = (struct sab_softc *)parent; sc->sc_bt = sc->sc_parent->sc_bt; sc->sc_portno = sa->sbt_portno; sc->sc_rend = sc->sc_rbuf + SABTTY_RBUF_SIZE; switch (sa->sbt_portno) { case 0: /* port A */ sc->sc_pvr_dtr = SAB_PVR_DTR_A; sc->sc_pvr_dsr = SAB_PVR_DSR_A; r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh, SAB_CHAN_A, SAB_CHANLEN, &sc->sc_bh); break; case 1: /* port B */ sc->sc_pvr_dtr = SAB_PVR_DTR_B; sc->sc_pvr_dsr = SAB_PVR_DSR_B; r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh, SAB_CHAN_B, SAB_CHANLEN, &sc->sc_bh); break; default: aprint_normal(": invalid channel: %u\n", sa->sbt_portno); return; } if (r != 0) { aprint_normal(": failed to allocate register subregion\n"); return; } sabtty_console_flags(sc); if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) { struct termios t; const char *acc; /* Let residual prom output drain */ DELAY(100000); switch (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) { case SABTTYF_CONS_IN: acc = "input"; break; case SABTTYF_CONS_OUT: acc = "output"; break; case SABTTYF_CONS_IN|SABTTYF_CONS_OUT: default: acc = "i/o"; break; } t.c_ispeed= 0; t.c_ospeed = 9600; t.c_cflag = CREAD | CS8 | HUPCL; sc->sc_tty->t_ospeed = 0; sabttyparam(sc, sc->sc_tty, &t); if (sc->sc_flags & SABTTYF_CONS_IN) { sabtty_cons_input = sc; cn_tab->cn_pollc = sab_cnpollc; cn_tab->cn_getc = sab_cngetc; maj = cdevsw_lookup_major(&sabtty_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(self)); shutdownhook_establish(sabtty_shutdown, sc); cn_init_magic(&sabtty_cnm_state); cn_set_magic("\047\001"); /* default magic is BREAK */ } if (sc->sc_flags & SABTTYF_CONS_OUT) { sabtty_tec_wait(sc); sabtty_cons_output = sc; cn_tab->cn_putc = sab_cnputc; maj = cdevsw_lookup_major(&sabtty_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(self)); } aprint_normal(": console %s", acc); } else { /* Not a console... */ sabtty_reset(sc); #ifdef KGDB if (is_kgdb) { sab_kgdb_init(sc); aprint_normal(": kgdb"); } #endif } aprint_normal("\n"); }
/* ARGSUSED */ STATIC void gtmpscattach(device_t parent, device_t self, void *aux) { struct gtmpsc_softc *sc = device_private(self); struct marvell_attach_args *mva = aux; bus_dma_segment_t segs; struct tty *tp; int rsegs, err, unit; void *kva; aprint_naive("\n"); aprint_normal(": Multi-Protocol Serial Controller\n"); if (mva->mva_unit != MVA_UNIT_DEFAULT) unit = mva->mva_unit; else unit = (mva->mva_offset == GTMPSC_BASE(0)) ? 0 : 1; #ifdef MPSC_CONSOLE if (cn_tab == >mpsc_consdev && cn_tab->cn_dev == makedev(0, unit)) { gtmpsc_cn_softc.sc_dev = self; memcpy(sc, >mpsc_cn_softc, sizeof(struct gtmpsc_softc)); sc->sc_flags = GTMPSC_CONSOLE; } else #endif { if (bus_space_subregion(mva->mva_iot, mva->mva_ioh, mva->mva_offset, mva->mva_size, &sc->sc_mpsch)) { aprint_error_dev(self, "Cannot map MPSC registers\n"); return; } if (bus_space_subregion(mva->mva_iot, mva->mva_ioh, GTSDMA_BASE(unit), GTSDMA_SIZE, &sc->sc_sdmah)) { aprint_error_dev(self, "Cannot map SDMA registers\n"); return; } sc->sc_dev = self; sc->sc_unit = unit; sc->sc_iot = mva->mva_iot; sc->sc_dmat = mva->mva_dmat; err = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, &segs, 1, &rsegs, BUS_DMA_NOWAIT); if (err) { aprint_error_dev(sc->sc_dev, "bus_dmamem_alloc error 0x%x\n", err); goto fail0; } err = bus_dmamem_map(sc->sc_dmat, &segs, 1, PAGE_SIZE, &kva, BUS_DMA_NOWAIT); if (err) { aprint_error_dev(sc->sc_dev, "bus_dmamem_map error 0x%x\n", err); goto fail1; } memset(kva, 0, PAGE_SIZE); /* paranoid/superfluous */ sc->sc_poll_sdmapage = kva; err = bus_dmamap_create(sc->sc_dmat, sizeof(gtmpsc_polltx_t), 1, sizeof(gtmpsc_polltx_t), 0, BUS_DMA_NOWAIT, &sc->sc_txdma_map); if (err != 0) { aprint_error_dev(sc->sc_dev, "bus_dmamap_create error 0x%x\n", err); goto fail2; } err = bus_dmamap_load(sc->sc_dmat, sc->sc_txdma_map, sc->sc_poll_sdmapage->tx, sizeof(gtmpsc_polltx_t), NULL, BUS_DMA_NOWAIT | BUS_DMA_READ | BUS_DMA_WRITE); if (err != 0) { aprint_error_dev(sc->sc_dev, "bus_dmamap_load tx error 0x%x\n", err); goto fail3; } err = bus_dmamap_create(sc->sc_dmat, sizeof(gtmpsc_pollrx_t), 1, sizeof(gtmpsc_pollrx_t), 0, BUS_DMA_NOWAIT, &sc->sc_rxdma_map); if (err != 0) { aprint_error_dev(sc->sc_dev, "bus_dmamap_create rx error 0x%x\n", err); goto fail4; } err = bus_dmamap_load(sc->sc_dmat, sc->sc_rxdma_map, sc->sc_poll_sdmapage->rx, sizeof(gtmpsc_pollrx_t), NULL, BUS_DMA_NOWAIT | BUS_DMA_READ | BUS_DMA_WRITE); if (err != 0) { aprint_error_dev(sc->sc_dev, "bus_dmamap_load rx error 0x%x\n", err); goto fail5; } sc->sc_brg = unit; /* XXXXX */ sc->sc_baudrate = GT_MPSC_DEFAULT_BAUD_RATE; } aprint_normal_dev(self, "with SDMA offset 0x%04x-0x%04x\n", GTSDMA_BASE(unit), GTSDMA_BASE(unit) + GTSDMA_SIZE - 1); sc->sc_rx_ready = 0; sc->sc_tx_busy = 0; sc->sc_tx_done = 0; sc->sc_tx_stopped = 0; sc->sc_heldchange = 0; gtmpsc_txdesc_init(sc); gtmpsc_rxdesc_init(sc); sc->sc_tty = tp = tty_alloc(); tp->t_oproc = gtmpscstart; tp->t_param = gtmpscparam; tty_attach(tp); mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH); /* * clear any pending SDMA interrupts for this unit */ (void) gt_sdma_icause(device_parent(sc->sc_dev), SDMA_INTR_RXBUF(sc->sc_unit) | SDMA_INTR_RXERR(sc->sc_unit) | SDMA_INTR_TXBUF(sc->sc_unit) | SDMA_INTR_TXEND(sc->sc_unit)); sc->sc_si = softint_establish(SOFTINT_SERIAL, gtmpsc_softintr, sc); if (sc->sc_si == NULL) panic("mpscattach: cannot softint_establish IPL_SOFTSERIAL"); shutdownhook_establish(gtmpsc_shutdownhook, sc); gtmpscinit_stop(sc); gtmpscinit_start(sc); if (sc->sc_flags & GTMPSC_CONSOLE) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(>mpsc_cdevsw); tp->t_dev = cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); aprint_normal_dev(self, "console\n"); } #ifdef KGDB /* * Allow kgdb to "take over" this port. If this is * the kgdb device, it has exclusive use. */ if (sc->sc_unit == gtmpsckgdbport) { #ifdef MPSC_CONSOLE if (sc->sc_unit == MPSC_CONSOLE) { aprint_error_dev(self, "(kgdb): cannot share with console\n"); return; } #endif sc->sc_flags |= GTMPSC_KGDB; aprint_normal_dev(self, "kgdb\n"); gtmpsc_txflush(sc); kgdb_attach(gtmpsc_kgdb_getc, gtmpsc_kgdb_putc, NULL); kgdb_dev = 123; /* unneeded, only to satisfy some tests */ gtmpsc_kgdb_attached = 1; kgdb_connect(1); } #endif /* KGDB */ return; fail5: bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxdma_map); fail4: bus_dmamap_unload(sc->sc_dmat, sc->sc_txdma_map); fail3: bus_dmamap_destroy(sc->sc_dmat, sc->sc_txdma_map); fail2: bus_dmamem_unmap(sc->sc_dmat, kva, PAGE_SIZE); fail1: bus_dmamem_free(sc->sc_dmat, &segs, 1); fail0: return; }
/* * cas_config: * * Attach a Cassini interface to the system. */ void cas_config(struct cas_softc *sc) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; struct mii_data *mii = &sc->sc_mii; struct mii_softc *child; int i, error; /* Make sure the chip is stopped. */ ifp->if_softc = sc; cas_reset(sc); /* * Allocate the control data structures, and create and load the * DMA map for it. */ if ((error = bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct cas_control_data), CAS_PAGE_SIZE, 0, &sc->sc_cdseg, 1, &sc->sc_cdnseg, 0)) != 0) { printf("\n%s: unable to allocate control data, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_0; } /* XXX should map this in with correct endianness */ if ((error = bus_dmamem_map(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg, sizeof(struct cas_control_data), (caddr_t *)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) { printf("\n%s: unable to map control data, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_1; } if ((error = bus_dmamap_create(sc->sc_dmatag, sizeof(struct cas_control_data), 1, sizeof(struct cas_control_data), 0, 0, &sc->sc_cddmamap)) != 0) { printf("\n%s: unable to create control data DMA map, " "error = %d\n", sc->sc_dev.dv_xname, error); goto fail_2; } if ((error = bus_dmamap_load(sc->sc_dmatag, sc->sc_cddmamap, sc->sc_control_data, sizeof(struct cas_control_data), NULL, 0)) != 0) { printf("\n%s: unable to load control data DMA map, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_3; } bzero(sc->sc_control_data, sizeof(struct cas_control_data)); /* * Create the receive buffer DMA maps. */ for (i = 0; i < CAS_NRXDESC; i++) { bus_dma_segment_t seg; caddr_t kva; int rseg; if ((error = bus_dmamem_alloc(sc->sc_dmatag, CAS_PAGE_SIZE, CAS_PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { printf("\n%s: unable to alloc rx DMA mem %d, " "error = %d\n", sc->sc_dev.dv_xname, i, error); goto fail_5; } sc->sc_rxsoft[i].rxs_dmaseg = seg; if ((error = bus_dmamem_map(sc->sc_dmatag, &seg, rseg, CAS_PAGE_SIZE, &kva, BUS_DMA_NOWAIT)) != 0) { printf("\n%s: unable to alloc rx DMA mem %d, " "error = %d\n", sc->sc_dev.dv_xname, i, error); goto fail_5; } sc->sc_rxsoft[i].rxs_kva = kva; if ((error = bus_dmamap_create(sc->sc_dmatag, CAS_PAGE_SIZE, 1, CAS_PAGE_SIZE, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) { printf("\n%s: unable to create rx DMA map %d, " "error = %d\n", sc->sc_dev.dv_xname, i, error); goto fail_5; } if ((error = bus_dmamap_load(sc->sc_dmatag, sc->sc_rxsoft[i].rxs_dmamap, kva, CAS_PAGE_SIZE, NULL, BUS_DMA_NOWAIT)) != 0) { printf("\n%s: unable to load rx DMA map %d, " "error = %d\n", sc->sc_dev.dv_xname, i, error); goto fail_5; } } /* * Create the transmit buffer DMA maps. */ for (i = 0; i < CAS_NTXDESC; i++) { if ((error = bus_dmamap_create(sc->sc_dmatag, MCLBYTES, CAS_NTXSEGS, MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->sc_txd[i].sd_map)) != 0) { printf("\n%s: unable to create tx DMA map %d, " "error = %d\n", sc->sc_dev.dv_xname, i, error); goto fail_6; } sc->sc_txd[i].sd_mbuf = NULL; } /* * From this point forward, the attachment cannot fail. A failure * before this point releases all resources that may have been * allocated. */ /* Announce ourselves. */ printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); /* Get RX FIFO size */ sc->sc_rxfifosize = 16 * 1024; /* Initialize ifnet structure. */ strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; ifp->if_start = cas_start; ifp->if_ioctl = cas_ioctl; ifp->if_watchdog = cas_watchdog; IFQ_SET_MAXLEN(&ifp->if_snd, CAS_NTXDESC - 1); IFQ_SET_READY(&ifp->if_snd); ifp->if_capabilities = IFCAP_VLAN_MTU; /* Initialize ifmedia structures and MII info */ mii->mii_ifp = ifp; mii->mii_readreg = cas_mii_readreg; mii->mii_writereg = cas_mii_writereg; mii->mii_statchg = cas_mii_statchg; ifmedia_init(&mii->mii_media, 0, cas_mediachange, cas_mediastatus); bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_MII_DATAPATH_MODE, 0); cas_mifinit(sc); if (sc->sc_mif_config & CAS_MIF_CONFIG_MDI1) { sc->sc_mif_config |= CAS_MIF_CONFIG_PHY_SEL; bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_MIF_CONFIG, sc->sc_mif_config); } mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); child = LIST_FIRST(&mii->mii_phys); if (child == NULL && sc->sc_mif_config & (CAS_MIF_CONFIG_MDI0|CAS_MIF_CONFIG_MDI1)) { /* * Try the external PCS SERDES if we didn't find any * MII devices. */ bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_MII_DATAPATH_MODE, CAS_MII_DATAPATH_SERDES); bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_MII_CONFIG, CAS_MII_CONFIG_ENABLE); mii->mii_readreg = cas_pcs_readreg; mii->mii_writereg = cas_pcs_writereg; mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_NOISOLATE); } child = LIST_FIRST(&mii->mii_phys); if (child == NULL) { /* No PHY attached */ ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); } else { /* * Walk along the list of attached MII devices and * establish an `MII instance' to `phy number' * mapping. We'll use this mapping in media change * requests to determine which phy to use to program * the MIF configuration register. */ for (; child != NULL; child = LIST_NEXT(child, mii_list)) { /* * Note: we support just two PHYs: the built-in * internal device and an external on the MII * connector. */ if (child->mii_phy > 1 || child->mii_inst > 1) { printf("%s: cannot accommodate MII device %s" " at phy %d, instance %d\n", sc->sc_dev.dv_xname, child->mii_dev.dv_xname, child->mii_phy, child->mii_inst); continue; } sc->sc_phys[child->mii_inst] = child->mii_phy; } /* * XXX - we can really do the following ONLY if the * phy indeed has the auto negotiation capability!! */ ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO); } /* Attach the interface. */ if_attach(ifp); ether_ifattach(ifp); sc->sc_sh = shutdownhook_establish(cas_shutdown, sc); if (sc->sc_sh == NULL) panic("cas_config: can't establish shutdownhook"); timeout_set(&sc->sc_tick_ch, cas_tick, sc); return; /* * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall through. */ fail_6: for (i = 0; i < CAS_NTXDESC; i++) { if (sc->sc_txd[i].sd_map != NULL) bus_dmamap_destroy(sc->sc_dmatag, sc->sc_txd[i].sd_map); } fail_5: for (i = 0; i < CAS_NRXDESC; i++) { if (sc->sc_rxsoft[i].rxs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmatag, sc->sc_rxsoft[i].rxs_dmamap); } bus_dmamap_unload(sc->sc_dmatag, sc->sc_cddmamap); fail_3: bus_dmamap_destroy(sc->sc_dmatag, sc->sc_cddmamap); fail_2: bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sc_control_data, sizeof(struct cas_control_data)); fail_1: bus_dmamem_free(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg); fail_0: return; }
void cgtwelveattach(struct device *parent, struct device *self, void *args) { struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self; struct confargs *ca = args; int node; int isconsole = 0; char *ps; node = ca->ca_ra.ra_node; printf(": %s", getpropstring(node, "model")); ps = getpropstring(node, "dev_id"); if (*ps != '\0') printf(" (%s)", ps); printf("\n"); isconsole = node == fbnode; sc->sc_phys = ca->ca_ra.ra_reg[0]; /* * Map registers */ sc->sc_dpu = (struct cgtwelve_dpu *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_DPU, sizeof(struct cgtwelve_dpu)); sc->sc_apu = (struct cgtwelve_apu *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_APU, sizeof(struct cgtwelve_apu)); sc->sc_ramdac = (struct cgtwelve_dac *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_DAC, sizeof(struct cgtwelve_dac)); /* * The console is using the 1-bit overlay plane, while the prom * will correctly report 32 bit depth. */ fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT, node, ca->ca_bustype); sc->sc_sunfb.sf_depth = 1; sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8; sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height * sc->sc_sunfb.sf_linebytes; sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR; /* * Map planes */ sc->sc_overlay = mapiodev(ca->ca_ra.ra_reg, sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0, round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR : CG12_SIZE_OVERLAY)); sc->sc_inten = mapiodev(ca->ca_ra.ra_reg, sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN, round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR : CG12_SIZE_COLOR24)); /* reset cursor & frame buffer controls */ sc->sc_sunfb.sf_depth = 0; /* force action */ cgtwelve_reset(sc, 1); sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay; sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); shutdownhook_establish(cgtwelve_prom, sc); } printf("%s: %dx%d", self->dv_xname, sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); ps = getpropstring(node, "ucoderev"); if (*ps != '\0') printf(", microcode rev. %s", ps); printf("\n"); fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole); }
static void lmc_pci_attach(struct device * const parent, struct device * const self, void * const aux) { u_int32_t revinfo, cfdainfo, id, ssid; pci_intr_handle_t intrhandle; const char *intrstr; unsigned csroffset = LMC_PCI_CSROFFSET; unsigned csrsize = LMC_PCI_CSRSIZE; lmc_csrptr_t csr_base; lmc_spl_t s; lmc_intrfunc_t (*intr_rtn)(void *) = lmc_intr_normal; lmc_softc_t * const sc = (lmc_softc_t *) self; struct pci_attach_args * const pa = (struct pci_attach_args *) aux; extern lmc_media_t lmc_hssi_media; extern lmc_media_t lmc_ds3_media; extern lmc_media_t lmc_t1_media; extern lmc_media_t lmc_ssi_media; revinfo = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFRV) & 0xFF; id = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFID); cfdainfo = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFDA); ssid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SSID); switch (PCI_CHIPID(ssid)) { case PCI_PRODUCT_LMC_HSSI: printf(": HSSI\n"); sc->lmc_media = &lmc_hssi_media; break; case PCI_PRODUCT_LMC_HSSIC: printf(": HSSIc\n"); sc->lmc_media = &lmc_hssi_media; break; case PCI_PRODUCT_LMC_DS3: printf(": DS3\n"); sc->lmc_media = &lmc_ds3_media; break; case PCI_PRODUCT_LMC_SSI: printf(": SSI\n"); sc->lmc_media = &lmc_ssi_media; break; case PCI_PRODUCT_LMC_DS1: printf(": T1\n"); sc->lmc_media = &lmc_t1_media; break; } sc->lmc_pci_busno = parent; sc->lmc_pci_devno = pa->pa_device; sc->lmc_chipid = LMC_21140A; sc->lmc_features |= LMC_HAVE_STOREFWD; if (sc->lmc_chipid == LMC_21140A && revinfo <= 0x22) sc->lmc_features |= LMC_HAVE_RXBADOVRFLW; if (cfdainfo & (TULIP_CFDA_SLEEP | TULIP_CFDA_SNOOZE)) { cfdainfo &= ~(TULIP_CFDA_SLEEP | TULIP_CFDA_SNOOZE); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_CFDA, cfdainfo); DELAY(11 * 1000); } bcopy(self->dv_xname, sc->lmc_if.if_xname, IFNAMSIZ); sc->lmc_if.if_softc = sc; sc->lmc_pc = pa->pa_pc; sc->lmc_revinfo = revinfo; sc->lmc_if.if_softc = sc; csr_base = 0; { bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; int ioh_valid, memh_valid; ioh_valid = (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL, 0) == 0); memh_valid = (pci_mapreg_map(pa, PCI_CBMA, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, NULL, NULL, 0) == 0); if (memh_valid) { sc->lmc_bustag = memt; sc->lmc_bushandle = memh; } else if (ioh_valid) { sc->lmc_bustag = iot; sc->lmc_bushandle = ioh; } else { printf("%s: unable to map device registers\n", sc->lmc_dev.dv_xname); return; } } sc->lmc_dmatag = pa->pa_dmat; if ((lmc_busdma_init(sc)) != 0) { printf("error initing bus_dma\n"); return; } lmc_initcsrs(sc, csr_base + csroffset, csrsize); lmc_initring(sc, &sc->lmc_rxinfo, sc->lmc_rxdescs, LMC_RXDESCS); lmc_initring(sc, &sc->lmc_txinfo, sc->lmc_txdescs, LMC_TXDESCS); lmc_gpio_mkinput(sc, 0xff); sc->lmc_gpio = 0; /* drive no signals yet */ sc->lmc_media->defaults(sc); sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN); /* down */ /* * Make sure there won't be any interrupts or such... */ LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); /* * Wait 10 microseconds (actually 50 PCI cycles but at * 33MHz that comes to two microseconds but wait a * bit longer anyways) */ DELAY(100); lmc_read_macaddr(sc); if (pci_intr_map(pa, &intrhandle)) { printf("%s: couldn't map interrupt\n", sc->lmc_dev.dv_xname); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); sc->lmc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET, intr_rtn, sc, self->dv_xname); if (sc->lmc_ih == NULL) { printf("%s: couldn't establish interrupt", sc->lmc_dev.dv_xname); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf("%s: pass %d.%d, serial " LMC_EADDR_FMT ", %s\n", sc->lmc_dev.dv_xname, (sc->lmc_revinfo & 0xF0) >> 4, sc->lmc_revinfo & 0x0F, LMC_EADDR_ARGS(sc->lmc_enaddr), intrstr); sc->lmc_ats = shutdownhook_establish(lmc_shutdown, sc); if (sc->lmc_ats == NULL) printf("%s: warning: couldn't establish shutdown hook\n", sc->lmc_xname); s = LMC_RAISESPL(); lmc_dec_reset(sc); lmc_reset(sc); lmc_attach(sc); LMC_RESTORESPL(s); }
/* * Attach this instance, and then all the sub-devices */ void espattach(device_t parent, device_t self, void *aux) { struct esp_softc *esc = device_private(self); struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; struct confargs *ca = aux; u_int *reg; int sz; /* * Set up glue for MI code early; we use some of it here. */ sc->sc_dev = self; sc->sc_glue = &esp_glue; esc->sc_node = ca->ca_node; esc->sc_pri = ca->ca_intr[0]; aprint_normal(" irq %d", esc->sc_pri); /* * Map my registers in. */ reg = ca->ca_reg; esc->sc_reg = mapiodev(ca->ca_baseaddr + reg[0], reg[1]); esc->sc_dmareg = mapiodev(ca->ca_baseaddr + reg[2], reg[3]); /* Allocate 16-byte aligned DMA command space */ esc->sc_dmacmd = dbdma_alloc(sizeof(dbdma_command_t) * 20); /* Other settings */ sc->sc_id = 7; sz = OF_getprop(ca->ca_node, "clock-frequency", &sc->sc_freq, sizeof(int)); if (sz != sizeof(int)) sc->sc_freq = 25000000; /* gimme MHz */ sc->sc_freq /= 1000000; /* esc->sc_dma->sc_esp = esc;*/ /* * XXX More of this should be in ncr53c9x_attach(), but * XXX should we really poke around the chip that much in * XXX the MI code? Think about this more... */ /* * Set up static configuration info. */ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; sc->sc_cfg2 = NCRCFG2_SCSI2; /* | NCRCFG2_FE */ sc->sc_cfg3 = NCRCFG3_CDB; sc->sc_rev = NCR_VARIANT_NCR53C94; /* * XXX minsync and maxxfer _should_ be set up in MI code, * XXX but it appears to have some dependency on what sort * XXX of DMA we're hooked up to, etc. */ /* * This is the value used to start sync negotiations * Note that the NCR register "SYNCTP" is programmed * in "clocks per byte", and has a minimum value of 4. * The SCSI period used in negotiation is one-fourth * of the time (in nanoseconds) needed to transfer one byte. * Since the chip's clock is given in MHz, we have the following * formula: 4 * period = (1000 / freq) * 4 */ sc->sc_minsync = 1000 / sc->sc_freq; sc->sc_maxxfer = 64 * 1024; /* and the interuppts */ intr_establish(esc->sc_pri, IST_EDGE, IPL_BIO, ncr53c9x_intr, sc); /* Reset SCSI bus when halt. */ shutdownhook_establish(esp_shutdownhook, sc); /* Do the common parts of attachment. */ sc->sc_adapter.adapt_minphys = minphys; sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request; ncr53c9x_attach(sc); /* Turn on target selection using the `DMA' method */ sc->sc_features |= NCR_F_DMASELECT; }
/* * ae_attach: * * Attach an ae interface to the system. */ void ae_attach(device_t parent, device_t self, void *aux) { const uint8_t *enaddr; prop_data_t ea; struct ae_softc *sc = device_private(self); struct arbus_attach_args *aa = aux; struct ifnet *ifp = &sc->sc_ethercom.ec_if; int i, error; sc->sc_dev = self; callout_init(&sc->sc_tick_callout, 0); printf(": Atheros AR531X 10/100 Ethernet\n"); /* * Try to get MAC address. */ ea = prop_dictionary_get(device_properties(sc->sc_dev), "mac-address"); if (ea == NULL) { printf("%s: unable to get mac-addr property\n", device_xname(sc->sc_dev)); return; } KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); enaddr = prop_data_data_nocopy(ea); /* Announce ourselves. */ printf("%s: Ethernet address %s\n", device_xname(sc->sc_dev), ether_sprintf(enaddr)); sc->sc_cirq = aa->aa_cirq; sc->sc_mirq = aa->aa_mirq; sc->sc_st = aa->aa_bst; sc->sc_dmat = aa->aa_dmat; SIMPLEQ_INIT(&sc->sc_txfreeq); SIMPLEQ_INIT(&sc->sc_txdirtyq); /* * Map registers. */ sc->sc_size = aa->aa_size; if ((error = bus_space_map(sc->sc_st, aa->aa_addr, sc->sc_size, 0, &sc->sc_sh)) != 0) { printf("%s: unable to map registers, error = %d\n", device_xname(sc->sc_dev), error); goto fail_0; } /* * Allocate the control data structures, and create and load the * DMA map for it. */ if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct ae_control_data), PAGE_SIZE, 0, &sc->sc_cdseg, 1, &sc->sc_cdnseg, 0)) != 0) { printf("%s: unable to allocate control data, error = %d\n", device_xname(sc->sc_dev), error); goto fail_1; } if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg, sizeof(struct ae_control_data), (void **)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) { printf("%s: unable to map control data, error = %d\n", device_xname(sc->sc_dev), error); goto fail_2; } if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct ae_control_data), 1, sizeof(struct ae_control_data), 0, 0, &sc->sc_cddmamap)) != 0) { printf("%s: unable to create control data DMA map, " "error = %d\n", device_xname(sc->sc_dev), error); goto fail_3; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, sc->sc_control_data, sizeof(struct ae_control_data), NULL, 0)) != 0) { printf("%s: unable to load control data DMA map, error = %d\n", device_xname(sc->sc_dev), error); goto fail_4; } /* * Create the transmit buffer DMA maps. */ for (i = 0; i < AE_TXQUEUELEN; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, AE_NTXSEGS, MCLBYTES, 0, 0, &sc->sc_txsoft[i].txs_dmamap)) != 0) { printf("%s: unable to create tx DMA map %d, " "error = %d\n", device_xname(sc->sc_dev), i, error); goto fail_5; } } /* * Create the receive buffer DMA maps. */ for (i = 0; i < AE_NRXDESC; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) { printf("%s: unable to create rx DMA map %d, " "error = %d\n", device_xname(sc->sc_dev), i, error); goto fail_6; } sc->sc_rxsoft[i].rxs_mbuf = NULL; } /* * Reset the chip to a known state. */ ae_reset(sc); /* * From this point forward, the attachment cannot fail. A failure * before this point releases all resources that may have been * allocated. */ sc->sc_flags |= AE_ATTACHED; /* * Initialize our media structures. This may probe the MII, if * present. */ sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = ae_mii_readreg; sc->sc_mii.mii_writereg = ae_mii_writereg; sc->sc_mii.mii_statchg = ae_mii_statchg; sc->sc_ethercom.ec_mii = &sc->sc_mii; ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange, ether_mediastatus); mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); } else ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); sc->sc_tick = ae_mii_tick; strcpy(ifp->if_xname, device_xname(sc->sc_dev)); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; sc->sc_if_flags = ifp->if_flags; ifp->if_ioctl = ae_ioctl; ifp->if_start = ae_start; ifp->if_watchdog = ae_watchdog; ifp->if_init = ae_init; ifp->if_stop = ae_stop; IFQ_SET_READY(&ifp->if_snd); /* * We can support 802.1Q VLAN-sized frames. */ sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; /* * Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, enaddr); ether_set_ifflags_cb(&sc->sc_ethercom, ae_ifflags_cb); rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); /* * Make sure the interface is shutdown during reboot. */ sc->sc_sdhook = shutdownhook_establish(ae_shutdown, sc); if (sc->sc_sdhook == NULL) printf("%s: WARNING: unable to establish shutdown hook\n", device_xname(sc->sc_dev)); /* * Add a suspend hook to make sure we come back up after a * resume. */ sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev), ae_power, sc); if (sc->sc_powerhook == NULL) printf("%s: WARNING: unable to establish power hook\n", device_xname(sc->sc_dev)); return; /* * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall through. */ fail_6: for (i = 0; i < AE_NRXDESC; i++) { if (sc->sc_rxsoft[i].rxs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].rxs_dmamap); } fail_5: for (i = 0; i < AE_TXQUEUELEN; i++) { if (sc->sc_txsoft[i].txs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmamap); } bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); fail_4: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); fail_3: bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, sizeof(struct ae_control_data)); fail_2: bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg); fail_1: bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size); fail_0: return; }
/* * The routine called by the low level scsi routine when it discovers * a device suitable for this driver. */ void sdattach(struct device *parent, struct device *self, void *aux) { struct sd_softc *sc = (struct sd_softc *)self; struct scsi_attach_args *sa = aux; struct disk_parms *dp = &sc->params; struct scsi_link *sc_link = sa->sa_sc_link; int sd_autoconf = scsi_autoconf | SCSI_SILENT | SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE; struct dk_cache dkc; int error, result; SC_DEBUG(sc_link, SDEV_DB2, ("sdattach:\n")); /* * Store information needed to contact our base driver */ sc->sc_link = sc_link; sc_link->interpret_sense = sd_interpret_sense; sc_link->device_softc = sc; if ((sc_link->flags & SDEV_ATAPI) && (sc_link->flags & SDEV_REMOVABLE)) sc_link->quirks |= SDEV_NOSYNCCACHE; if (!(sc_link->inqdata.flags & SID_RelAdr)) sc_link->quirks |= SDEV_ONLYBIG; /* * Note if this device is ancient. This is used in sdminphys(). */ if (!(sc_link->flags & SDEV_ATAPI) && SCSISPC(sa->sa_inqbuf->version) == 0) sc->flags |= SDF_ANCIENT; /* * Use the subdriver to request information regarding * the drive. We cannot use interrupts yet, so the * request must specify this. */ printf("\n"); scsi_xsh_set(&sc->sc_xsh, sc_link, sdstart); timeout_set(&sc->sc_timeout, (void (*)(void *))scsi_xsh_add, &sc->sc_xsh); /* Spin up non-UMASS devices ready or not. */ if ((sc->sc_link->flags & SDEV_UMASS) == 0) scsi_start(sc_link, SSS_START, sd_autoconf); /* * Some devices (e.g. Blackberry Pearl) won't admit they have * media loaded unless its been locked in. */ if ((sc_link->flags & SDEV_REMOVABLE) != 0) scsi_prevent(sc_link, PR_PREVENT, sd_autoconf); /* Check that it is still responding and ok. */ error = scsi_test_unit_ready(sc->sc_link, TEST_READY_RETRIES * 3, sd_autoconf); if (error) result = SDGP_RESULT_OFFLINE; else result = sd_get_parms(sc, &sc->params, sd_autoconf); if ((sc_link->flags & SDEV_REMOVABLE) != 0) scsi_prevent(sc_link, PR_ALLOW, sd_autoconf); switch (result) { case SDGP_RESULT_OK: printf("%s: %lluMB, %lu bytes/sector, %llu sectors", sc->sc_dev.dv_xname, dp->disksize / (1048576 / dp->secsize), dp->secsize, dp->disksize); printf("\n"); break; case SDGP_RESULT_OFFLINE: break; #ifdef DIAGNOSTIC default: panic("sdattach: unknown result (%#x) from get_parms", result); break; #endif } /* * Initialize disk structures. */ sc->sc_dk.dk_name = sc->sc_dev.dv_xname; bufq_init(&sc->sc_bufq, BUFQ_FIFO); /* * Enable write cache by default. */ memset(&dkc, 0, sizeof(dkc)); if (sd_ioctl_cache(sc, DIOCGCACHE, &dkc) == 0 && dkc.wrcache == 0) { dkc.wrcache = 1; sd_ioctl_cache(sc, DIOCSCACHE, &dkc); } /* * Establish a shutdown hook so that we can ensure that * our data has actually made it onto the platter at * shutdown time. Note that this relies on the fact * that the shutdown hook code puts us at the head of * the list (thus guaranteeing that our hook runs before * our ancestors'). */ if ((sc->sc_sdhook = shutdownhook_establish(sd_shutdown, sc)) == NULL) printf("%s: WARNING: unable to establish shutdown hook\n", sc->sc_dev.dv_xname); /* Attach disk. */ disk_attach(&sc->sc_dev, &sc->sc_dk); }
/* * Initialise our interface to the controller. */ int cac_init(struct cac_softc *sc, const char *intrstr, int startfw) { struct cac_controller_info cinfo; int error, rseg, size, i; bus_dma_segment_t seg; struct cac_ccb *ccb; char firm[8]; if (intrstr != NULL) aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); SIMPLEQ_INIT(&sc->sc_ccb_free); SIMPLEQ_INIT(&sc->sc_ccb_queue); mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM); cv_init(&sc->sc_ccb_cv, "cacccb"); size = sizeof(struct cac_ccb) * CAC_MAX_CCBS; if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "unable to allocate CCBs, error = %d\n", error); return (-1); } if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size, (void **)&sc->sc_ccbs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { aprint_error_dev(sc->sc_dev, "unable to map CCBs, error = %d\n", error); return (-1); } if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { aprint_error_dev(sc->sc_dev, "unable to create CCB DMA map, error = %d\n", error); return (-1); } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ccbs, size, NULL, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "unable to load CCB DMA map, error = %d\n", error); return (-1); } sc->sc_ccbs_paddr = sc->sc_dmamap->dm_segs[0].ds_addr; memset(sc->sc_ccbs, 0, size); ccb = (struct cac_ccb *)sc->sc_ccbs; for (i = 0; i < CAC_MAX_CCBS; i++, ccb++) { /* Create the DMA map for this CCB's data */ error = bus_dmamap_create(sc->sc_dmat, CAC_MAX_XFER, CAC_SG_SIZE, CAC_MAX_XFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap_xfer); if (error) { aprint_error_dev(sc->sc_dev, "can't create ccb dmamap (%d)\n", error); break; } ccb->ccb_flags = 0; ccb->ccb_paddr = sc->sc_ccbs_paddr + i * sizeof(struct cac_ccb); SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_chain); } /* Start firmware background tasks, if needed. */ if (startfw) { if (cac_cmd(sc, CAC_CMD_START_FIRMWARE, &cinfo, sizeof(cinfo), 0, 0, CAC_CCB_DATA_IN, NULL)) { aprint_error_dev(sc->sc_dev, "CAC_CMD_START_FIRMWARE failed\n"); return (-1); } } if (cac_cmd(sc, CAC_CMD_GET_CTRL_INFO, &cinfo, sizeof(cinfo), 0, 0, CAC_CCB_DATA_IN, NULL)) { aprint_error_dev(sc->sc_dev, "CAC_CMD_GET_CTRL_INFO failed\n"); return (-1); } strlcpy(firm, cinfo.firm_rev, 4+1); printf("%s: %d channels, firmware <%s>\n", device_xname(sc->sc_dev), cinfo.scsi_chips, firm); /* Limit number of units to size of our sc_unitmask */ sc->sc_nunits = cinfo.num_drvs; if (sc->sc_nunits > sizeof(sc->sc_unitmask) * NBBY) sc->sc_nunits = sizeof(sc->sc_unitmask) * NBBY; /* Attach our units */ sc->sc_unitmask = 0; cac_rescan(sc->sc_dev, "cac", 0); /* Set our `shutdownhook' before we start any device activity. */ if (cac_sdh == NULL) cac_sdh = shutdownhook_establish(cac_shutdown, NULL); mutex_enter(&sc->sc_mutex); (*sc->sc_cl.cl_intr_enable)(sc, CAC_INTR_ENABLE); mutex_exit(&sc->sc_mutex); #if NBIO > 0 if (bio_register(sc->sc_dev, cac_ioctl) != 0) aprint_error_dev(sc->sc_dev, "controller registration failed"); else sc->sc_ioctl = cac_ioctl; if (cac_create_sensors(sc) != 0) aprint_error_dev(sc->sc_dev, "unable to create sensors\n"); #endif return (0); }
/* * Attach and initialize a cgtwelve. */ void cgtwelveattach(struct device *parent, struct device *self, void *args) { struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self; struct sbus_attach_args *sa = args; bus_space_tag_t bt; bus_space_handle_t bh; int node, isconsole = 0; char *ps; bt = sa->sa_bustag; node = sa->sa_node; printf(": %s", getpropstring(node, "model")); ps = getpropstring(node, "dev_id"); if (*ps != '\0') printf(" (%s)", ps); printf("\n"); isconsole = node == fbnode; if (sa->sa_nreg == 0) { printf("%s: no SBus registers!\n", self->dv_xname); return; } sc->sc_bustag = bt; /* * Map registers */ if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + CG12_OFF_DPU, sizeof(struct cgtwelve_dpu), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map DPU registers\n", self->dv_xname); return; } sc->sc_dpu = bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + CG12_OFF_APU, sizeof(struct cgtwelve_apu), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map APU registers\n", self->dv_xname); return; } sc->sc_apu = bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + CG12_OFF_DAC, sizeof(struct cgtwelve_dac), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map RAMDAC registers\n", self->dv_xname); return; } sc->sc_ramdac = bus_space_vaddr(bt, bh); /* * The console is using the 1-bit overlay plane, while the prom * will correctly report 32 bit depth. */ fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT, node, 0); sc->sc_sunfb.sf_depth = 1; sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8; sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height * sc->sc_sunfb.sf_linebytes; sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR; /* * Map planes */ if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + (sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0), round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR : CG12_SIZE_OVERLAY), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map overlay plane\n", self->dv_xname); return; } sc->sc_overlay = bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN), round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR : CG12_SIZE_COLOR24), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map color plane\n", self->dv_xname); return; } sc->sc_inten = bus_space_vaddr(bt, bh); sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset + (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN)); /* reset cursor & frame buffer controls */ sc->sc_sunfb.sf_depth = 0; /* force action */ cgtwelve_reset(sc, 1); sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay; sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, 0, isconsole); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); shutdownhook_establish(cgtwelve_prom, sc); } printf("%s: %dx%d", self->dv_xname, sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); ps = getpropstring(node, "ucoderev"); if (*ps != '\0') printf(", microcode rev. %s", ps); printf("\n"); fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole); }
void tcxattach(struct device *parent, struct device *self, void *args) { struct tcx_softc *sc = (struct tcx_softc *)self; struct confargs *ca = args; int node, pri; int isconsole = 0; char *nam = NULL; vaddr_t thc_offset; pri = ca->ca_ra.ra_intr[0].int_pri; printf(" pri %d: ", pri); node = ca->ca_ra.ra_node; isconsole = node == fbnode; if (ca->ca_ra.ra_nreg < TCX_NREG) { printf("expected %d registers, got %d\n", TCX_NREG, ca->ca_ra.ra_nreg); return; } nam = getpropstring(node, "model"); if (*nam != '\0') printf("%s, ", nam); /* * Copy the register address spaces needed for mmap operation. */ sc->sc_phys[0] = ca->ca_ra.ra_reg[TCX_REG_DFB8]; sc->sc_phys[1] = ca->ca_ra.ra_reg[TCX_REG_DFB24]; /* * Can't trust the PROM range len here, it is only 4 bytes on the * 8-bit model. Not that it matters much anyway since we map in * pages. */ sc->sc_bt = (volatile struct bt_regs *) mapiodev(&ca->ca_ra.ra_reg[TCX_REG_CMAP], 0, sizeof *sc->sc_bt); /* * For some reason S24 PROM sets up TEC and THC ranges at the * right addresses (701000 and 301000), while 8 bit TCX doesn't * (and uses 70000 and 30000) - be sure to only compensate on 8 bit * models. */ if (((vaddr_t)ca->ca_ra.ra_reg[TCX_REG_THC].rr_paddr & 0x1000) != 0) thc_offset = 0; else thc_offset = 0x1000; sc->sc_thc = (volatile struct tcx_thc *) mapiodev(&ca->ca_ra.ra_reg[TCX_REG_THC], thc_offset, sizeof *sc->sc_thc); /* * Find out frame buffer geometry, so that we know how much * memory to map. */ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); sc->sc_dfb8 = mapiodev(&ca->ca_ra.ra_reg[TCX_REG_DFB8], 0, round_page(sc->sc_sunfb.sf_fbsize)); /* * If the frame buffer advertizes itself as the 8 bit model, or * if the PROM ranges are too small, limit ourselves to 8 bit * operations. * * Further code needing to know which capabilities the frame buffer * has will rely on sc_cplane being non-zero if 24 bit operation * is possible. */ if (!node_has_property(node, "tcx-8-bit") && ca->ca_ra.ra_reg[TCX_REG_RDFB32].rr_len >= sc->sc_sunfb.sf_fbsize * 4) { sc->sc_cplane = (paddr_t)ca->ca_ra.ra_reg[TCX_REG_RDFB32].rr_paddr; } printf("%dx%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height, sc->sc_cplane == 0 ? 8 : 24); /* * Set up mappings for the acceleration code. This may fail. */ tcx_accel_init(sc, ca); /* reset cursor & frame buffer controls */ tcx_reset(sc, 8); /* enable video */ tcx_burner(sc, 1, 0); sc->sc_sunfb.sf_ro.ri_hw = sc; sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_dfb8; fbwscons_init(&sc->sc_sunfb, isconsole); fbwscons_setcolormap(&sc->sc_sunfb, tcx_setcolor); /* * Now plug accelerated console routines, if possible. */ tcx_accel_plug(sc, ca); sc->sc_ih.ih_fun = tcx_intr; sc->sc_ih.ih_arg = sc; intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); shutdownhook_establish(tcx_prom, sc); } fbwscons_attach(&sc->sc_sunfb, &tcx_accessops, isconsole); }