static int fimd_attach(device_t dev) { struct panel_info panel; struct fimd_softc *sc; device_t gpio_dev; int reg; sc = device_get_softc(dev); sc->dev = dev; if (bus_alloc_resources(dev, fimd_spec, sc->res)) { device_printf(dev, "could not allocate resources\n"); return (ENXIO); } /* Memory interface */ sc->bst = rman_get_bustag(sc->res[0]); sc->bsh = rman_get_bushandle(sc->res[0]); sc->bst_disp = rman_get_bustag(sc->res[1]); sc->bsh_disp = rman_get_bushandle(sc->res[1]); sc->bst_sysreg = rman_get_bustag(sc->res[2]); sc->bsh_sysreg = rman_get_bushandle(sc->res[2]); if (get_panel_info(sc, &panel)) { device_printf(dev, "Can't get panel info\n"); return (ENXIO); } panel.fixvclk = 0; panel.ivclk = 0; panel.clkval_f = 2; sc->panel = &panel; /* Get the GPIO device, we need this to give power to USB */ gpio_dev = devclass_get_device(devclass_find("gpio"), 0); if (gpio_dev == NULL) { /* TODO */ } reg = bus_space_read_4(sc->bst_sysreg, sc->bsh_sysreg, 0x214); reg |= FIMDBYPASS_DISP1; bus_space_write_4(sc->bst_sysreg, sc->bsh_sysreg, 0x214, reg); sc->sc_info.fb_width = panel.width; sc->sc_info.fb_height = panel.height; sc->sc_info.fb_stride = sc->sc_info.fb_width * 2; sc->sc_info.fb_bpp = sc->sc_info.fb_depth = 16; sc->sc_info.fb_size = sc->sc_info.fb_height * sc->sc_info.fb_stride; sc->sc_info.fb_vbase = (intptr_t)kmem_alloc_contig(kernel_arena, sc->sc_info.fb_size, M_ZERO, 0, ~0, PAGE_SIZE, 0, VM_MEMATTR_UNCACHEABLE); sc->sc_info.fb_pbase = (intptr_t)vtophys(sc->sc_info.fb_vbase); #if 0 printf("%dx%d [%d]\n", sc->sc_info.fb_width, sc->sc_info.fb_height, sc->sc_info.fb_stride); printf("pbase == 0x%08x\n", sc->sc_info.fb_pbase); #endif memset((int8_t *)sc->sc_info.fb_vbase, 0x0, sc->sc_info.fb_size); fimd_init(sc); sc->sc_info.fb_name = device_get_nameunit(dev); /* Ask newbus to attach framebuffer device to me. */ sc->sc_fbd = device_add_child(dev, "fbd", device_get_unit(dev)); if (sc->sc_fbd == NULL) device_printf(dev, "Can't attach fbd device\n"); if (device_probe_and_attach(sc->sc_fbd) != 0) { device_printf(sc->dev, "Failed to attach fbd device\n"); } return (0); }
/* * Function name: twa_attach * Description: Allocates pci resources; updates sc; adds a node to the * sysctl tree to expose the driver version; makes calls * (to the Common Layer) to initialize ctlr, and to * attach to CAM. * * Input: dev -- bus device corresponding to the ctlr * Output: None * Return value: 0 -- success * non-zero-- failure */ static TW_INT32 twa_attach(device_t dev) { struct twa_softc *sc = device_get_softc(dev); TW_UINT32 command; TW_INT32 bar_num; TW_INT32 bar0_offset; TW_INT32 bar_size; TW_INT32 error; tw_osli_dbg_dprintf(3, sc, "entered"); sc->ctlr_handle.osl_ctlr_ctxt = sc; /* Initialize the softc structure. */ sc->bus_dev = dev; sc->device_id = pci_get_device(dev); /* Initialize the mutexes right here. */ sc->io_lock = &(sc->io_lock_handle); mtx_init(sc->io_lock, "tw_osl_io_lock", NULL, MTX_SPIN); sc->q_lock = &(sc->q_lock_handle); mtx_init(sc->q_lock, "tw_osl_q_lock", NULL, MTX_SPIN); sc->sim_lock = &(sc->sim_lock_handle); mtx_init(sc->sim_lock, "tw_osl_sim_lock", NULL, MTX_DEF | MTX_RECURSE); sysctl_ctx_init(&sc->sysctl_ctxt); sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctxt, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, device_get_nameunit(dev), CTLFLAG_RD, 0, ""); if (sc->sysctl_tree == NULL) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2000, "Cannot add sysctl tree node", ENXIO); return(ENXIO); } SYSCTL_ADD_STRING(&sc->sysctl_ctxt, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, "driver_version", CTLFLAG_RD, TW_OSL_DRIVER_VERSION_STRING, 0, "TWA driver version"); /* Make sure we are going to be able to talk to this board. */ command = pci_read_config(dev, PCIR_COMMAND, 2); if ((command & PCIM_CMD_PORTEN) == 0) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2001, "Register window not available", ENXIO); tw_osli_free_resources(sc); return(ENXIO); } /* Force the busmaster enable bit on, in case the BIOS forgot. */ command |= PCIM_CMD_BUSMASTEREN; pci_write_config(dev, PCIR_COMMAND, command, 2); /* Allocate the PCI register window. */ if ((error = tw_cl_get_pci_bar_info(sc->device_id, TW_CL_BAR_TYPE_MEM, &bar_num, &bar0_offset, &bar_size))) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x201F, "Can't get PCI BAR info", error); tw_osli_free_resources(sc); return(error); } sc->reg_res_id = PCIR_BARS + bar0_offset; if ((sc->reg_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->reg_res_id), 0, ~0, 1, RF_ACTIVE)) == NULL) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2002, "Can't allocate register window", ENXIO); tw_osli_free_resources(sc); return(ENXIO); } sc->bus_tag = rman_get_bustag(sc->reg_res); sc->bus_handle = rman_get_bushandle(sc->reg_res); /* Allocate and register our interrupt. */ sc->irq_res_id = 0; if ((sc->irq_res = bus_alloc_resource(sc->bus_dev, SYS_RES_IRQ, &(sc->irq_res_id), 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2003, "Can't allocate interrupt", ENXIO); tw_osli_free_resources(sc); return(ENXIO); } if ((error = bus_setup_intr(sc->bus_dev, sc->irq_res, INTR_TYPE_CAM | INTR_MPSAFE, NULL, twa_pci_intr, sc, &sc->intr_handle))) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2004, "Can't set up interrupt", error); tw_osli_free_resources(sc); return(error); } if ((error = tw_osli_alloc_mem(sc))) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2005, "Memory allocation failure", error); tw_osli_free_resources(sc); return(error); } /* Initialize the Common Layer for this controller. */ if ((error = tw_cl_init_ctlr(&sc->ctlr_handle, sc->flags, sc->device_id, TW_OSLI_MAX_NUM_REQUESTS, TW_OSLI_MAX_NUM_AENS, sc->non_dma_mem, sc->dma_mem, sc->dma_mem_phys ))) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2006, "Failed to initialize Common Layer/controller", error); tw_osli_free_resources(sc); return(error); } /* Create the control device. */ sc->ctrl_dev = make_dev(&twa_cdevsw, device_get_unit(sc->bus_dev), UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "twa%d", device_get_unit(sc->bus_dev)); sc->ctrl_dev->si_drv1 = sc; if ((error = tw_osli_cam_attach(sc))) { tw_osli_free_resources(sc); tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2007, "Failed to initialize CAM", error); return(error); } return(0); }
/* Attach the interface. Allocate softc structures */ static int sln_attach(device_t dev) { struct sln_softc *sc = device_get_softc(dev); struct ifnet *ifp = &sc->arpcom.ac_if; unsigned char eaddr[ETHER_ADDR_LEN]; int rid; int error = 0; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); /* TODO: power state change */ pci_enable_busmaster(dev); rid = SL_RID; sc->sln_res = bus_alloc_resource_any(dev, SL_RES, &rid, RF_ACTIVE); if (sc->sln_res == NULL) { device_printf(dev, "couldn't map ports/memory\n"); error = ENXIO; goto fail; } sc->sln_bustag = rman_get_bustag(sc->sln_res); sc->sln_bushandle = rman_get_bushandle(sc->sln_res); /* alloc pci irq */ rid = 0; sc->sln_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (sc->sln_irq == NULL) { device_printf(dev, "couldn't map interrupt\n"); bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res); error = ENXIO; goto fail; } /* Get MAC address */ ((uint32_t *)(&eaddr))[0] = be32toh(SLN_READ_4(sc, SL_MAC_ADDR0)); ((uint16_t *)(&eaddr))[2] = be16toh(SLN_READ_4(sc, SL_MAC_ADDR1)); /* alloc rx buffer space */ sc->sln_bufdata.sln_rx_buf = contigmalloc(SL_RX_BUFLEN, M_DEVBUF, M_WAITOK, 0, 0xffffffff, PAGE_SIZE, 0); if (sc->sln_bufdata.sln_rx_buf == NULL) { device_printf(dev, "no memory for rx buffers!\n"); bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq); bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res); error = ENXIO; goto fail; } callout_init(&sc->sln_state); ifp->if_softc = sc; ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_init = sln_init; ifp->if_start = sln_tx; ifp->if_ioctl = sln_ioctl; ifp->if_watchdog = sln_watchdog; ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); ifq_set_ready(&ifp->if_snd); /* initial media */ ifmedia_init(&sc->ifmedia, 0, sln_media_upd, sln_media_stat); /* supported media types */ ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_HDX, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_HDX, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL); /* Choose a default media. */ ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO); ether_ifattach(ifp, eaddr, NULL); ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->sln_irq)); error = bus_setup_intr(dev, sc->sln_irq, INTR_MPSAFE, sln_interrupt, sc, &sc->sln_intrhand, ifp->if_serializer); if (error) { bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sln_irq); bus_release_resource(dev, SL_RES, SL_RID, sc->sln_res); ether_ifdetach(ifp); device_printf(dev, "couldn't set up irq\n"); goto fail; } return 0; fail: return error; }
static int tws_attach(device_t dev) { struct tws_softc *sc = device_get_softc(dev); u_int32_t bar; int error=0,i; /* no tracing yet */ /* Look up our softc and initialize its fields. */ sc->tws_dev = dev; sc->device_id = pci_get_device(dev); sc->subvendor_id = pci_get_subvendor(dev); sc->subdevice_id = pci_get_subdevice(dev); /* Intialize mutexes */ mtx_init( &sc->q_lock, "tws_q_lock", NULL, MTX_DEF); mtx_init( &sc->sim_lock, "tws_sim_lock", NULL, MTX_DEF); mtx_init( &sc->gen_lock, "tws_gen_lock", NULL, MTX_DEF); mtx_init( &sc->io_lock, "tws_io_lock", NULL, MTX_DEF | MTX_RECURSE); if ( tws_init_trace_q(sc) == FAILURE ) printf("trace init failure\n"); /* send init event */ mtx_lock(&sc->gen_lock); tws_send_event(sc, TWS_INIT_START); mtx_unlock(&sc->gen_lock); #if _BYTE_ORDER == _BIG_ENDIAN TWS_TRACE(sc, "BIG endian", 0, 0); #endif /* sysctl context setup */ sysctl_ctx_init(&sc->tws_clist); sc->tws_oidp = SYSCTL_ADD_NODE(&sc->tws_clist, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, device_get_nameunit(dev), CTLFLAG_RD, 0, ""); if ( sc->tws_oidp == NULL ) { tws_log(sc, SYSCTL_TREE_NODE_ADD); goto attach_fail_1; } SYSCTL_ADD_STRING(&sc->tws_clist, SYSCTL_CHILDREN(sc->tws_oidp), OID_AUTO, "driver_version", CTLFLAG_RD, TWS_DRIVER_VERSION_STRING, 0, "TWS driver version"); pci_enable_busmaster(dev); bar = pci_read_config(dev, TWS_PCI_BAR0, 4); TWS_TRACE_DEBUG(sc, "bar0 ", bar, 0); bar = pci_read_config(dev, TWS_PCI_BAR1, 4); bar = bar & ~TWS_BIT2; TWS_TRACE_DEBUG(sc, "bar1 ", bar, 0); /* MFA base address is BAR2 register used for * push mode. Firmware will evatualy move to * pull mode during witch this needs to change */ #ifndef TWS_PULL_MODE_ENABLE sc->mfa_base = (u_int64_t)pci_read_config(dev, TWS_PCI_BAR2, 4); sc->mfa_base = sc->mfa_base & ~TWS_BIT2; TWS_TRACE_DEBUG(sc, "bar2 ", sc->mfa_base, 0); #endif /* allocate MMIO register space */ sc->reg_res_id = TWS_PCI_BAR1; /* BAR1 offset */ if ((sc->reg_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->reg_res_id), 0, ~0, 1, RF_ACTIVE)) == NULL) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_1; } sc->bus_tag = rman_get_bustag(sc->reg_res); sc->bus_handle = rman_get_bushandle(sc->reg_res); #ifndef TWS_PULL_MODE_ENABLE /* Allocate bus space for inbound mfa */ sc->mfa_res_id = TWS_PCI_BAR2; /* BAR2 offset */ if ((sc->mfa_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->mfa_res_id), 0, ~0, 0x100000, RF_ACTIVE)) == NULL) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_2; } sc->bus_mfa_tag = rman_get_bustag(sc->mfa_res); sc->bus_mfa_handle = rman_get_bushandle(sc->mfa_res); #endif /* Allocate and register our interrupt. */ sc->intr_type = TWS_INTx; /* default */ if ( tws_enable_msi ) sc->intr_type = TWS_MSI; if ( tws_setup_irq(sc) == FAILURE ) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_3; } /* * Create a /dev entry for this device. The kernel will assign us * a major number automatically. We use the unit number of this * device as the minor number and name the character device * "tws<unit>". */ sc->tws_cdev = make_dev(&tws_cdevsw, device_get_unit(dev), UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "tws%u", device_get_unit(dev)); sc->tws_cdev->si_drv1 = sc; if ( tws_init(sc) == FAILURE ) { tws_log(sc, TWS_INIT_FAILURE); goto attach_fail_4; } if ( tws_init_ctlr(sc) == FAILURE ) { tws_log(sc, TWS_CTLR_INIT_FAILURE); goto attach_fail_4; } if ((error = tws_cam_attach(sc))) { tws_log(sc, TWS_CAM_ATTACH); goto attach_fail_4; } /* send init complete event */ mtx_lock(&sc->gen_lock); tws_send_event(sc, TWS_INIT_COMPLETE); mtx_unlock(&sc->gen_lock); TWS_TRACE_DEBUG(sc, "attached successfully", 0, sc->device_id); return(0); attach_fail_4: tws_teardown_intr(sc); destroy_dev(sc->tws_cdev); attach_fail_3: for(i=0;i<sc->irqs;i++) { if ( sc->irq_res[i] ){ if (bus_release_resource(sc->tws_dev, SYS_RES_IRQ, sc->irq_res_id[i], sc->irq_res[i])) TWS_TRACE(sc, "bus irq res", 0, 0); } } #ifndef TWS_PULL_MODE_ENABLE attach_fail_2: #endif if ( sc->mfa_res ){ if (bus_release_resource(sc->tws_dev, SYS_RES_MEMORY, sc->mfa_res_id, sc->mfa_res)) TWS_TRACE(sc, "bus release ", 0, sc->mfa_res_id); } if ( sc->reg_res ){ if (bus_release_resource(sc->tws_dev, SYS_RES_MEMORY, sc->reg_res_id, sc->reg_res)) TWS_TRACE(sc, "bus release2 ", 0, sc->reg_res_id); } attach_fail_1: mtx_destroy(&sc->q_lock); mtx_destroy(&sc->sim_lock); mtx_destroy(&sc->gen_lock); mtx_destroy(&sc->io_lock); sysctl_ctx_free(&sc->tws_clist); return (ENXIO); }
static void fwe_identify(driver_t *driver, device_t parent) { BUS_ADD_CHILD(parent, 0, "fwe", device_get_unit(parent)); }
static int mpt_pci_attach(device_t dev) { struct mpt_softc *mpt; int iqd; uint32_t data, cmd; int mpt_io_bar, mpt_mem_bar; mpt = (struct mpt_softc*)device_get_softc(dev); switch (pci_get_device(dev)) { case MPI_MANUFACTPAGE_DEVICEID_FC909_FB: case MPI_MANUFACTPAGE_DEVICEID_FC909: case MPI_MANUFACTPAGE_DEVICEID_FC919: case MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC929: case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC929X: case MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC919X: case MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC949E: case MPI_MANUFACTPAGE_DEVICEID_FC949X: mpt->is_fc = 1; break; case MPI_MANUFACTPAGE_DEVID_SAS1078: case MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB: mpt->is_1078 = 1; /* FALLTHROUGH */ case MPI_MANUFACTPAGE_DEVID_SAS1064: case MPI_MANUFACTPAGE_DEVID_SAS1064A: case MPI_MANUFACTPAGE_DEVID_SAS1064E: case MPI_MANUFACTPAGE_DEVID_SAS1066: case MPI_MANUFACTPAGE_DEVID_SAS1066E: case MPI_MANUFACTPAGE_DEVID_SAS1068: case MPI_MANUFACTPAGE_DEVID_SAS1068A_FB: case MPI_MANUFACTPAGE_DEVID_SAS1068E: case MPI_MANUFACTPAGE_DEVID_SAS1068E_FB: mpt->is_sas = 1; break; default: mpt->is_spi = 1; break; } mpt->dev = dev; mpt->unit = device_get_unit(dev); mpt->raid_resync_rate = MPT_RAID_RESYNC_RATE_DEFAULT; mpt->raid_mwce_setting = MPT_RAID_MWCE_DEFAULT; mpt->raid_queue_depth = MPT_RAID_QUEUE_DEPTH_DEFAULT; mpt->verbose = MPT_PRT_NONE; mpt->role = MPT_ROLE_NONE; mpt->mpt_ini_id = MPT_INI_ID_NONE; #ifdef __sparc64__ if (mpt->is_spi) mpt->mpt_ini_id = OF_getscsinitid(dev); #endif mpt_set_options(mpt); if (mpt->verbose == MPT_PRT_NONE) { mpt->verbose = MPT_PRT_WARN; /* Print INFO level (if any) if bootverbose is set */ mpt->verbose += (bootverbose != 0)? 1 : 0; } /* Make sure memory access decoders are enabled */ cmd = pci_read_config(dev, PCIR_COMMAND, 2); if ((cmd & PCIM_CMD_MEMEN) == 0) { device_printf(dev, "Memory accesses disabled"); return (ENXIO); } /* * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set. */ cmd |= PCIM_CMD_SERRESPEN | PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN; pci_write_config(dev, PCIR_COMMAND, cmd, 2); /* * Make sure we've disabled the ROM. */ data = pci_read_config(dev, PCIR_BIOS, 4); data &= ~PCIM_BIOS_ENABLE; pci_write_config(dev, PCIR_BIOS, data, 4); /* * Is this part a dual? * If so, link with our partner (around yet) */ switch (pci_get_device(dev)) { case MPI_MANUFACTPAGE_DEVICEID_FC929: case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC949E: case MPI_MANUFACTPAGE_DEVICEID_FC949X: case MPI_MANUFACTPAGE_DEVID_53C1030: case MPI_MANUFACTPAGE_DEVID_53C1030ZC: mpt_link_peer(mpt); break; default: break; } /* * Figure out which are the I/O and MEM Bars */ data = pci_read_config(dev, PCIR_BAR(0), 4); if (PCI_BAR_IO(data)) { /* BAR0 is IO, BAR1 is memory */ mpt_io_bar = 0; mpt_mem_bar = 1; } else { /* BAR0 is memory, BAR1 is IO */ mpt_mem_bar = 0; mpt_io_bar = 1; } /* * Set up register access. PIO mode is required for * certain reset operations (but must be disabled for * some cards otherwise). */ mpt_io_bar = PCIR_BAR(mpt_io_bar); mpt->pci_pio_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &mpt_io_bar, RF_ACTIVE); if (mpt->pci_pio_reg == NULL) { if (bootverbose) { device_printf(dev, "unable to map registers in PIO mode\n"); } } else { mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg); mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg); } mpt_mem_bar = PCIR_BAR(mpt_mem_bar); mpt->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &mpt_mem_bar, RF_ACTIVE); if (mpt->pci_reg == NULL) { if (bootverbose || mpt->is_sas || mpt->pci_pio_reg == NULL) { device_printf(dev, "Unable to memory map registers.\n"); } if (mpt->is_sas || mpt->pci_pio_reg == NULL) { device_printf(dev, "Giving Up.\n"); goto bad; } if (bootverbose) { device_printf(dev, "Falling back to PIO mode.\n"); } mpt->pci_st = mpt->pci_pio_st; mpt->pci_sh = mpt->pci_pio_sh; } else { mpt->pci_st = rman_get_bustag(mpt->pci_reg); mpt->pci_sh = rman_get_bushandle(mpt->pci_reg); } /* Get a handle to the interrupt */ iqd = 0; if (mpt->msi_enable) { /* * First try to alloc an MSI-X message. If that * fails, then try to alloc an MSI message instead. */ if (pci_msix_count(dev) == 1) { mpt->pci_msi_count = 1; if (pci_alloc_msix(dev, &mpt->pci_msi_count) == 0) { iqd = 1; } else { mpt->pci_msi_count = 0; } } if (iqd == 0 && pci_msi_count(dev) == 1) { mpt->pci_msi_count = 1; if (pci_alloc_msi(dev, &mpt->pci_msi_count) == 0) { iqd = 1; } else { mpt->pci_msi_count = 0; } } } mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, RF_ACTIVE | (mpt->pci_msi_count ? 0 : RF_SHAREABLE)); if (mpt->pci_irq == NULL) { device_printf(dev, "could not allocate interrupt\n"); goto bad; } MPT_LOCK_SETUP(mpt); /* Disable interrupts at the part */ mpt_disable_ints(mpt); /* Register the interrupt handler */ if (mpt_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, NULL, mpt_pci_intr, mpt, &mpt->ih)) { device_printf(dev, "could not setup interrupt\n"); goto bad; } /* Allocate dma memory */ if (mpt_dma_mem_alloc(mpt)) { mpt_prt(mpt, "Could not allocate DMA memory\n"); goto bad; } #if 0 /* * Save the PCI config register values * * Hard resets are known to screw up the BAR for diagnostic * memory accesses (Mem1). * * Using Mem1 is known to make the chip stop responding to * configuration space transfers, so we need to save it now */ mpt_read_config_regs(mpt); #endif /* * Disable PIO until we need it */ if (mpt->is_sas) { pci_disable_io(dev, SYS_RES_IOPORT); } /* Initialize the hardware */ if (mpt->disabled == 0) { if (mpt_attach(mpt) != 0) { goto bad; } } else { mpt_prt(mpt, "device disabled at user request\n"); goto bad; } mpt->eh = EVENTHANDLER_REGISTER(shutdown_post_sync, mpt_pci_shutdown, dev, SHUTDOWN_PRI_DEFAULT); if (mpt->eh == NULL) { mpt_prt(mpt, "shutdown event registration failed\n"); (void) mpt_detach(mpt); goto bad; } return (0); bad: mpt_dma_mem_free(mpt); mpt_free_bus_resources(mpt); mpt_unlink_peer(mpt); MPT_LOCK_DESTROY(mpt); /* * but return zero to preserve unit numbering */ return (0); }
int ex_attach(device_t dev) { struct ex_softc * sc = device_get_softc(dev); struct ifnet * ifp; struct ifmedia * ifm; int error; uint16_t temp; ifp = sc->ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); return (ENOSPC); } /* work out which set of irq <-> internal tables to use */ if (ex_card_type(sc->enaddr) == CARD_TYPE_EX_10_PLUS) { sc->irq2ee = plus_irq2eemap; sc->ee2irq = plus_ee2irqmap; } else { sc->irq2ee = irq2eemap; sc->ee2irq = ee2irqmap; } sc->mem_size = CARD_RAM_SIZE; /* XXX This should be read from the card itself. */ /* * Initialize the ifnet structure. */ ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; ifp->if_start = ex_start; ifp->if_ioctl = ex_ioctl; ifp->if_init = ex_init; IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts); mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); callout_init_mtx(&sc->timer, &sc->lock, 0); temp = ex_eeprom_read(sc, EE_W5); if (temp & EE_W5_PORT_TPE) ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); if (temp & EE_W5_PORT_BNC) ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL); if (temp & EE_W5_PORT_AUI) ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_NONE, 0, NULL); ifmedia_set(&sc->ifmedia, ex_get_media(sc)); ifm = &sc->ifmedia; ifm->ifm_media = ifm->ifm_cur->ifm_media; ex_ifmedia_upd(ifp); /* * Attach the interface. */ ether_ifattach(ifp, sc->enaddr); error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, ex_intr, (void *)sc, &sc->ih); if (error) { device_printf(dev, "bus_setup_intr() failed!\n"); ether_ifdetach(ifp); mtx_destroy(&sc->lock); return (error); } return(0); }
static int atiixp_pci_attach(device_t dev) { struct atiixp_info *sc; int i; sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc"); sc->dev = dev; /* * Default DMA segments per playback / recording channel */ sc->dma_segs = ATI_IXP_DMA_CHSEGS; pci_set_powerstate(dev, PCI_POWERSTATE_D0); pci_enable_busmaster(dev); sc->regid = PCIR_BAR(0); sc->regtype = SYS_RES_MEMORY; sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid, RF_ACTIVE); if (!sc->reg) { device_printf(dev, "unable to allocate register space\n"); goto bad; } sc->st = rman_get_bustag(sc->reg); sc->sh = rman_get_bushandle(sc->reg); sc->bufsz = pcm_getbuffersize(dev, 4096, ATI_IXP_DEFAULT_BUFSZ, 65536); sc->irqid = 0; sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid, RF_ACTIVE | RF_SHAREABLE); if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, atiixp_intr, sc, &sc->ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } /* * Let the user choose the best DMA segments. */ if (resource_int_value(device_get_name(dev), device_get_unit(dev), "dma_segs", &i) == 0) { if (i < ATI_IXP_DMA_CHSEGS_MIN) i = ATI_IXP_DMA_CHSEGS_MIN; if (i > ATI_IXP_DMA_CHSEGS_MAX) i = ATI_IXP_DMA_CHSEGS_MAX; sc->dma_segs = i; } /* * round the value to the nearest ^2 */ i = 0; while (sc->dma_segs >> i) i++; sc->dma_segs = 1 << (i - 1); if (sc->dma_segs < ATI_IXP_DMA_CHSEGS_MIN) sc->dma_segs = ATI_IXP_DMA_CHSEGS_MIN; else if (sc->dma_segs > ATI_IXP_DMA_CHSEGS_MAX) sc->dma_segs = ATI_IXP_DMA_CHSEGS_MAX; /* * DMA tag for scatter-gather buffers and link pointers */ if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, /*flags*/0, &sc->parent_dmat) != 0) { device_printf(dev, "unable to create dma tag\n"); goto bad; } if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/sc->dma_segs * ATI_IXP_NCHANS * sizeof(struct atiixp_dma_op), /*nsegments*/1, /*maxsegz*/0x3ffff, /*flags*/0, &sc->sgd_dmat) != 0) { device_printf(dev, "unable to create dma tag\n"); goto bad; } if (bus_dmamem_alloc(sc->sgd_dmat, (void **)&sc->sgd_table, BUS_DMA_NOWAIT, &sc->sgd_dmamap) == -1) goto bad; if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table, sc->dma_segs * ATI_IXP_NCHANS * sizeof(struct atiixp_dma_op), atiixp_dma_cb, sc, 0)) goto bad; atiixp_chip_pre_init(sc); sc->delayed_attach.ich_func = atiixp_chip_post_init; sc->delayed_attach.ich_arg = sc; sc->delayed_attach.ich_desc = "snd_atiixp"; if (cold == 0 || config_intrhook_establish(&sc->delayed_attach) != 0) { sc->delayed_attach.ich_func = NULL; atiixp_chip_post_init(sc); } return 0; bad: atiixp_release_resource(sc); return ENXIO; }
int ahc_pci_map_registers(struct ahc_softc *ahc) { struct resource *regs; u_int command; int regs_type; int regs_id; int allow_memio; command = aic_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); regs = NULL; regs_type = 0; regs_id = 0; /* Retrieve the per-device 'allow_memio' hint */ if (resource_int_value(device_get_name(ahc->dev_softc), device_get_unit(ahc->dev_softc), "allow_memio", &allow_memio) != 0) { if (bootverbose) device_printf(ahc->dev_softc, "Defaulting to MEMIO "); #ifdef AHC_ALLOW_MEMIO if (bootverbose) kprintf("on\n"); allow_memio = 1; #else if (bootverbose) kprintf("off\n"); allow_memio = 0; #endif } if ((allow_memio != 0) && (command & PCIM_CMD_MEMEN) != 0) { regs_type = SYS_RES_MEMORY; regs_id = AHC_PCI_MEMADDR; regs = bus_alloc_resource_any(ahc->dev_softc, regs_type, ®s_id, RF_ACTIVE); if (regs != NULL) { ahc->tag = rman_get_bustag(regs); ahc->bsh = rman_get_bushandle(regs); /* * Do a quick test to see if memory mapped * I/O is functioning correctly. */ if (ahc_pci_test_register_access(ahc) != 0) { device_printf(ahc->dev_softc, "PCI Device %d:%d:%d failed memory " "mapped test. Using PIO.\n", aic_get_pci_bus(ahc->dev_softc), aic_get_pci_slot(ahc->dev_softc), aic_get_pci_function(ahc->dev_softc)); bus_release_resource(ahc->dev_softc, regs_type, regs_id, regs); regs = NULL; } else { command &= ~PCIM_CMD_PORTEN; aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1); } } } if (regs == NULL && (command & PCIM_CMD_PORTEN) != 0) { regs_type = SYS_RES_IOPORT; regs_id = AHC_PCI_IOADDR; regs = bus_alloc_resource_any(ahc->dev_softc, regs_type, ®s_id, RF_ACTIVE); if (regs != NULL) { ahc->tag = rman_get_bustag(regs); ahc->bsh = rman_get_bushandle(regs); if (ahc_pci_test_register_access(ahc) != 0) { device_printf(ahc->dev_softc, "PCI Device %d:%d:%d failed I/O " "mapped test.\n", aic_get_pci_bus(ahc->dev_softc), aic_get_pci_slot(ahc->dev_softc), aic_get_pci_function(ahc->dev_softc)); bus_release_resource(ahc->dev_softc, regs_type, regs_id, regs); regs = NULL; } else { command &= ~PCIM_CMD_MEMEN; aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1); } } } if (regs == NULL) { device_printf(ahc->dev_softc, "can't allocate register resources\n"); return (ENOMEM); } ahc->platform_data->regs_res_type = regs_type; ahc->platform_data->regs_res_id = regs_id; ahc->platform_data->regs = regs; return (0); }
static int atse_attach_nexus(device_t dev) { struct atse_softc *sc; int error; sc = device_get_softc(dev); sc->atse_dev = dev; sc->atse_unit = device_get_unit(dev); /* Get RX and TX IRQ and FIFO information from hints. */ error = atse_resource_int(dev, "rx_irq", &sc->atse_rx_irq); error += atse_resource_long(dev, "rx_maddr", &sc->atse_rx_maddr); error += atse_resource_long(dev, "rx_msize", &sc->atse_rx_msize); error += atse_resource_long(dev, "rxc_maddr", &sc->atse_rxc_maddr); error += atse_resource_long(dev, "rxc_msize", &sc->atse_rxc_msize); error += atse_resource_int(dev, "tx_irq", &sc->atse_tx_irq); error += atse_resource_long(dev, "tx_maddr", &sc->atse_tx_maddr); error += atse_resource_long(dev, "tx_msize", &sc->atse_tx_msize); error += atse_resource_long(dev, "txc_maddr", &sc->atse_txc_maddr); error += atse_resource_long(dev, "txc_msize", &sc->atse_txc_msize); if (error != 0) return (error); /* Avalon-MM, atse management register region. */ sc->atse_mem_rid = 0; sc->atse_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->atse_mem_rid, RF_ACTIVE); if (sc->atse_mem_res == NULL) { device_printf(dev, "failed to map memory for ctrl region\n"); return (ENXIO); } /* * (Optional) RX IRQ and memory mapped regions. * 0x00: 2 * 32bit FIFO data, * 0x20: 8 * 32bit FIFO ctrl, Avalon-ST Sink to Avalon-MM R-Slave. */ sc->atse_rx_irq_rid = 0; sc->atse_rx_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->atse_rx_irq_rid, sc->atse_rx_irq, sc->atse_rx_irq, 1, RF_ACTIVE | RF_SHAREABLE); sc->atse_rx_mem_rid = 0; sc->atse_rx_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->atse_rx_mem_rid, sc->atse_rx_maddr, sc->atse_rx_maddr + sc->atse_rx_msize, sc->atse_rx_msize, RF_ACTIVE); if (sc->atse_rx_mem_res == NULL) { device_printf(dev, "failed to map memory for RX\n"); goto err; } sc->atse_rxc_mem_rid = 0; sc->atse_rxc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->atse_rxc_mem_rid, sc->atse_rxc_maddr, sc->atse_rxc_maddr + sc->atse_rxc_msize, sc->atse_rxc_msize, RF_ACTIVE); if (sc->atse_rxc_mem_res == NULL) { device_printf(dev, "failed to map memory for RX control\n"); goto err; } /* * (Optional) TX IRQ and memory mapped regions. * 0x00: 2 * 32bit FIFO data, * 0x20: 8 * 32bit FIFO ctrl, Avalon-MM W-Slave to Avalon-ST Source. */ sc->atse_tx_irq_rid = 0; sc->atse_tx_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->atse_tx_irq_rid, sc->atse_tx_irq, sc->atse_tx_irq, 1, RF_ACTIVE | RF_SHAREABLE); sc->atse_tx_mem_rid = 0; sc->atse_tx_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->atse_tx_mem_rid, sc->atse_tx_maddr, sc->atse_tx_maddr + sc->atse_tx_msize, sc->atse_tx_msize, RF_ACTIVE); if (sc->atse_tx_mem_res == NULL) { device_printf(dev, "failed to map memory for TX\n"); goto err; } sc->atse_txc_mem_rid = 0; sc->atse_txc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->atse_txc_mem_rid, sc->atse_txc_maddr, sc->atse_txc_maddr + sc->atse_txc_msize, sc->atse_txc_msize, RF_ACTIVE); if (sc->atse_txc_mem_res == NULL) { device_printf(dev, "failed to map memory for TX control\n"); goto err; } error = atse_attach(dev); if (error) goto err; return (0); err: /* Cleanup. */ atse_detach_resources(dev); return (error); }
static int ofwfb_scattach(device_t dev) { return (sc_attach_unit(device_get_unit(dev), device_get_flags(dev) | SC_AUTODETECT_KBD)); }
/*---------------------------------------------------------------------------* * isic_probe_usrtai - probe for USR *---------------------------------------------------------------------------*/ int isic_probe_usrtai(device_t dev) { size_t unit = device_get_unit(dev); /* get unit */ struct l1_softc *sc = 0; /* pointer to softc */ void *ih = 0; /* dummy */ /* check max unit range */ if(unit >= ISIC_MAXUNIT) { kprintf("isic%d: Error, unit %d >= ISIC_MAXUNIT for USR Sportster TA!\n", unit, unit); return(ENXIO); } sc = &l1_sc[unit]; /* get pointer to softc */ sc->sc_unit = unit; /* set unit */ /* see if an io base was supplied */ if(!(sc->sc_resources.io_base[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_resources.io_rid[0], 0ul, ~0ul, 1, RF_ACTIVE))) { kprintf("isic%d: Could not get iobase for USR Sportster TA!\n", unit); return(ENXIO); } /* set io base */ sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); /* release io base */ bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], sc->sc_resources.io_base[0]); /* check if we got an iobase */ switch(sc->sc_port) { case 0x200: case 0x208: case 0x210: case 0x218: case 0x220: case 0x228: case 0x230: case 0x238: case 0x240: case 0x248: case 0x250: case 0x258: case 0x260: case 0x268: case 0x270: case 0x278: break; default: kprintf("isic%d: Error, invalid iobase 0x%x specified for USR Sportster TA!\n", unit, sc->sc_port); return(0); break; } /* allocate all the ports needed */ if(usrtai_alloc_port(dev)) { kprintf("isic%d: Could not get the ports for USR Sportster TA!\n", unit); isic_detach_common(dev); return(ENXIO); } /* get our irq */ if(!(sc->sc_resources.irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_resources.irq_rid, 0ul, ~0ul, 1, RF_ACTIVE))) { kprintf("isic%d: Could not get an irq for USR Sportster TA!\n",unit); isic_detach_common(dev); return ENXIO; } /* get the irq number */ sc->sc_irq = rman_get_start(sc->sc_resources.irq); /* register interrupt routine */ bus_setup_intr(dev, sc->sc_resources.irq, 0, (void(*)(void *))(isicintr), sc, &ih, NULL); /* check IRQ validity */ if(intr_no[sc->sc_irq] == 0) { kprintf("isic%d: Error, invalid IRQ [%d] specified for USR Sportster TA!\n", unit, sc->sc_irq); return(1); } /* setup ISAC access routines */ sc->clearirq = NULL; sc->readreg = usrtai_read_reg; sc->writereg = usrtai_write_reg; sc->readfifo = usrtai_read_fifo; sc->writefifo = usrtai_write_fifo; /* setup card type */ sc->sc_cardtyp = CARD_TYPEP_USRTA; /* setup IOM bus type */ sc->sc_bustyp = BUS_TYPE_IOM2; sc->sc_ipac = 0; sc->sc_bfifolen = HSCX_FIFO_LEN; /* setup ISAC and HSCX base addr */ ISAC_BASE = (caddr_t)sc->sc_port + USR_ISAC_OFF; HSCX_A_BASE = (caddr_t)sc->sc_port + USR_HSCXA_OFF; HSCX_B_BASE = (caddr_t)sc->sc_port + USR_HSCXB_OFF; /* * Read HSCX A/B VSTR. Expected value for USR Sportster TA based * boards is 0x05 in the least significant bits. */ if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) ) { kprintf("isic%d: HSCX VSTR test failed for USR Sportster TA\n", unit); kprintf("isic%d: HSC0: VSTR: %#x\n", unit, HSCX_READ(0, H_VSTR)); kprintf("isic%d: HSC1: VSTR: %#x\n", unit, HSCX_READ(1, H_VSTR)); return (1); } return (0); }
/*---------------------------------------------------------------------------* * allocate an io port - based on code in isa_isic.c *---------------------------------------------------------------------------*/ static int usrtai_alloc_port(device_t dev) { size_t unit = device_get_unit(dev); struct l1_softc *sc = &l1_sc[unit]; int i, num = 0; bus_size_t base; /* 49 io mappings: 1 config and 48x8 registers */ /* config at offset 0x8000 */ base = sc->sc_port + 0x8000; if (base < 0 || base > 0x0ffff) return 1; sc->sc_resources.io_rid[num] = num; bus_set_resource(dev, SYS_RES_IOPORT, num, base, 1); if(!(sc->sc_resources.io_base[num] = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_resources.io_rid[num], 0ul, ~0ul, 1, RF_ACTIVE))) { kprintf("isic%d: Error, failed to reserve io #%dport %#x!\n", unit, num, base); isic_detach_common(dev); return(ENXIO); } num++; /* HSCX A at offset 0 */ base = sc->sc_port; for (i = 0; i < 16; i++) { if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) return 1; sc->sc_resources.io_rid[num] = num; bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); if(!(sc->sc_resources.io_base[num] = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_resources.io_rid[num], 0ul, ~0ul, 1, RF_ACTIVE))) { kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); isic_detach_common(dev); return(ENXIO); } ++num; } /* HSCX B at offset 0x4000 */ base = sc->sc_port + 0x4000; for (i = 0; i < 16; i++) { if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) return 1; sc->sc_resources.io_rid[num] = num; bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); if(!(sc->sc_resources.io_base[num] = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_resources.io_rid[num], 0ul, ~0ul, 1, RF_ACTIVE))) { kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); isic_detach_common(dev); return(ENXIO); } ++num; } /* ISAC at offset 0xc000 */ base = sc->sc_port + 0xc000; for (i = 0; i < 16; i++) { if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff) return 1; sc->sc_resources.io_rid[num] = num; bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8); if(!(sc->sc_resources.io_base[num] = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_resources.io_rid[num], 0ul, ~0ul, 1, RF_ACTIVE))) { kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024); isic_detach_common(dev); return(ENXIO); } ++num; } return(0); }
/* * Attach the interface. */ static int lgue_attach(device_t dev) { struct lgue_softc *sc; struct usb_attach_arg *uaa; struct ifnet *ifp; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; u_char eaddr[ETHER_ADDR_LEN]; usbd_status err; sc = device_get_softc(dev); uaa = device_get_ivars(dev); sc->lgue_ctl_iface = uaa->iface; sc->lgue_udev = uaa->device; /* It has only config but in case... */ if (usbd_set_config_no(sc->lgue_udev, LGUE_CONFIG_NO, 0)) { device_printf(dev, "setting config no %d failed\n", LGUE_CONFIG_NO); return(ENXIO); } /* Get control and data intefaces */ id = usbd_get_interface_descriptor(uaa->iface); sc->lgue_ctl_iface_no = id->bInterfaceNumber; sc->lgue_data_iface_no = lgue_get_data_iface_no(sc->lgue_udev, id); if (sc->lgue_data_iface_no == -1) { device_printf(dev, "no data interface number\n"); goto bad; } /* Claim data interface */ for (i = 0; i < uaa->nifaces; ++i) { if (uaa->ifaces[i] != NULL) { id = usbd_get_interface_descriptor(uaa->ifaces[i]); if (id != NULL && id->bInterfaceNumber == sc->lgue_data_iface_no) { err = usbd_set_interface(uaa->ifaces[i], LGUE_ALTERNATE_SETTING); if ( err != USBD_NORMAL_COMPLETION) { device_printf(dev, "no alternate data interface. err:%s\n", usbd_errstr(err)); goto bad; } sc->lgue_data_iface = uaa->ifaces[i]; uaa->ifaces[i] = NULL; } } } if (sc->lgue_data_iface == NULL) { device_printf(dev, "no data interface\n"); goto bad; } /* Find data interface endpoints */ id = usbd_get_interface_descriptor(sc->lgue_data_iface); sc->lgue_ed[LGUE_ENDPT_RX] = sc->lgue_ed[LGUE_ENDPT_TX] = -1; for (i = 0; i < id->bNumEndpoints; ++i) { ed = usbd_interface2endpoint_descriptor(sc->lgue_data_iface, i); if (!ed) { device_printf(dev, "couldn't get endpoint descriptor %d\n", i); goto bad; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->lgue_ed[LGUE_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->lgue_ed[LGUE_ENDPT_TX] = ed->bEndpointAddress; } } if (sc->lgue_ed[LGUE_ENDPT_RX] == -1) { device_printf(dev, "couldn't find data bilk in\n"); goto bad; } if (sc->lgue_ed[LGUE_ENDPT_TX] == -1) { device_printf(dev, "couldn't find data bilk out\n"); goto bad; } /* Find control interface endpoint */ id = usbd_get_interface_descriptor(sc->lgue_ctl_iface); sc->lgue_ed[LGUE_ENDPT_INTR] = -1; for (i = 0; i < id->bNumEndpoints; ++i) { ed = usbd_interface2endpoint_descriptor(sc->lgue_ctl_iface, i); if (!ed) { device_printf(dev, "couldn't get endpoint descriptor %d\n", i); goto bad; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->lgue_ed[LGUE_ENDPT_INTR] = ed->bEndpointAddress; } } if (sc->lgue_ed[LGUE_ENDPT_INTR] == -1) { device_printf(dev, "couldn't find interrupt bilk in\n"); goto bad; } /* Create interface */ ifp = &sc->lgue_arpcom.ac_if; ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); lgue_getmac(sc, eaddr); ifp->if_mtu = lgue_getmtu(sc); ifp->if_data.ifi_mtu = ifp->if_mtu; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_baudrate = 10000000; ifp->if_ioctl = lgue_ioctl; ifp->if_start = lgue_start; ifp->if_watchdog = lgue_watchdog; ifp->if_init = lgue_init; ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); ifq_set_ready(&ifp->if_snd); /* Call attach routine */ ether_ifattach(ifp, eaddr, NULL); usb_register_netisr(); sc->lgue_dying = 0; return(0); bad: return(ENXIO); }
static int sata_channel_attach(device_t dev) { struct sata_softc *sc; struct ata_channel *ch; uint64_t work; int error, i; sc = device_get_softc(device_get_parent(dev)); ch = device_get_softc(dev); if (ch->attached) return (0); ch->dev = dev; ch->unit = device_get_unit(dev); ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE | ATA_SATA; /* Set legacy ATA resources. */ for (i = ATA_DATA; i <= ATA_COMMAND; i++) { ch->r_io[i].res = sc->sc_mem_res; ch->r_io[i].offset = SATA_SHADOWR_BASE(ch->unit) + (i << 2); } ch->r_io[ATA_CONTROL].res = sc->sc_mem_res; ch->r_io[ATA_CONTROL].offset = SATA_SHADOWR_CONTROL(ch->unit); ch->r_io[ATA_IDX_ADDR].res = sc->sc_mem_res; ata_default_registers(dev); /* Set SATA resources. */ ch->r_io[ATA_SSTATUS].res = sc->sc_mem_res; ch->r_io[ATA_SSTATUS].offset = SATA_SATA_SSTATUS(ch->unit); ch->r_io[ATA_SERROR].res = sc->sc_mem_res; ch->r_io[ATA_SERROR].offset = SATA_SATA_SERROR(ch->unit); ch->r_io[ATA_SCONTROL].res = sc->sc_mem_res; ch->r_io[ATA_SCONTROL].offset = SATA_SATA_SCONTROL(ch->unit); ata_generic_hw(dev); ch->hw.begin_transaction = sata_channel_begin_transaction; ch->hw.end_transaction = sata_channel_end_transaction; ch->hw.status = sata_channel_status; /* Set DMA resources */ ata_dmainit(dev); ch->dma.setprd = sata_channel_dmasetprd; /* Clear work area */ KASSERT(sc->sc_edma_qlen * (sizeof(struct sata_crqb) + sizeof(struct sata_crpb)) <= ch->dma.max_iosize, ("insufficient DMA memory for request/response queues.\n")); bzero(ch->dma.work, sc->sc_edma_qlen * (sizeof(struct sata_crqb) + sizeof(struct sata_crpb))); bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* Turn off EDMA engine */ error = sata_edma_ctrl(dev, 0); if (error) { ata_dmafini(dev); return (error); } /* * Initialize EDMA engine: * - Native Command Queuing off, * - Non-Queued operation, * - Host Queue Cache enabled. */ SATA_OUTL(sc, SATA_EDMA_CFG(ch->unit), SATA_EDMA_CFG_HQCACHE | (sc->sc_version == 1) ? SATA_EDMA_CFG_QL128 : 0); /* Set request queue pointers */ work = ch->dma.work_bus; SATA_OUTL(sc, SATA_EDMA_REQBAHR(ch->unit), work >> 32); SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), work & 0xFFFFFFFF); SATA_OUTL(sc, SATA_EDMA_REQOPR(ch->unit), work & 0xFFFFFFFF); /* Set response queue pointers */ work += sc->sc_edma_qlen * sizeof(struct sata_crqb); SATA_OUTL(sc, SATA_EDMA_RESBAHR(ch->unit), work >> 32); SATA_OUTL(sc, SATA_EDMA_RESIPR(ch->unit), work & 0xFFFFFFFF); SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), work & 0xFFFFFFFF); /* Clear any outstanding interrupts */ ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR)); SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0); SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0); SATA_OUTL(sc, SATA_ICR, ~(SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit))); /* Umask channel interrupts */ SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF); SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) | SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) | SATA_MICR_ERR(ch->unit)); ch->attached = 1; return (ata_attach(dev)); }
static int ahc_pci_attach(device_t dev) { struct ahc_pci_identity *entry; struct ahc_softc *ahc; char *name; int error; entry = ahc_find_pci_device(dev); if (entry == NULL) return (ENXIO); /* * Allocate a softc for this card and * set it up for attachment by our * common detect routine. */ name = kmalloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_INTWAIT); strcpy(name, device_get_nameunit(dev)); ahc = ahc_alloc(dev, name); if (ahc == NULL) return (ENOMEM); ahc_set_unit(ahc, device_get_unit(dev)); /* * Should we bother disabling 39Bit addressing * based on installed memory? */ if (sizeof(bus_addr_t) > 4) ahc->flags |= AHC_39BIT_ADDRESSING; /* Allocate a dmatag for our SCB DMA maps */ /* XXX Should be a child of the PCI bus dma tag */ error = aic_dma_tag_create(ahc, /*parent*/NULL, /*alignment*/1, /*boundary*/0, (ahc->flags & AHC_39BIT_ADDRESSING) ? 0x7FFFFFFFFFULL : BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, /*nsegments*/AHC_NSEG, /*maxsegsz*/AHC_MAXTRANSFER_SIZE, /*flags*/0, &ahc->parent_dmat); if (error != 0) { kprintf("ahc_pci_attach: Could not allocate DMA tag " "- error %d\n", error); ahc_free(ahc); return (ENOMEM); } ahc->dev_softc = dev; error = ahc_pci_config(ahc, entry); if (error != 0) { ahc_free(ahc); return (error); } ahc_attach(ahc); return (0); }
/* * Parse a _CST package and set up its Cx states. Since the _CST object * can change dynamically, our notify handler may call this function * to clean up and probe the new _CST package. */ static int acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) { struct acpi_cx *cx_ptr; ACPI_STATUS status; ACPI_BUFFER buf; ACPI_OBJECT *top; ACPI_OBJECT *pkg; uint32_t count; int i; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; status = AcpiEvaluateObject(sc->cpu_handle, "_CST", NULL, &buf); if (ACPI_FAILURE(status)) return (ENXIO); /* _CST is a package with a count and at least one Cx package. */ top = (ACPI_OBJECT *)buf.Pointer; if (!ACPI_PKG_VALID(top, 2) || acpi_PkgInt32(top, 0, &count) != 0) { device_printf(sc->cpu_dev, "invalid _CST package\n"); AcpiOsFree(buf.Pointer); return (ENXIO); } if (count != top->Package.Count - 1) { device_printf(sc->cpu_dev, "invalid _CST state count (%d != %d)\n", count, top->Package.Count - 1); count = top->Package.Count - 1; } if (count > MAX_CX_STATES) { device_printf(sc->cpu_dev, "_CST has too many states (%d)\n", count); count = MAX_CX_STATES; } /* Set up all valid states. */ sc->cpu_cx_count = 0; cx_ptr = sc->cpu_cx_states; for (i = 0; i < count; i++) { pkg = &top->Package.Elements[i + 1]; if (!ACPI_PKG_VALID(pkg, 4) || acpi_PkgInt32(pkg, 1, &cx_ptr->type) != 0 || acpi_PkgInt32(pkg, 2, &cx_ptr->trans_lat) != 0 || acpi_PkgInt32(pkg, 3, &cx_ptr->power) != 0) { device_printf(sc->cpu_dev, "skipping invalid Cx state package\n"); continue; } /* Validate the state to see if we should use it. */ switch (cx_ptr->type) { case ACPI_STATE_C1: sc->cpu_non_c3 = i; cx_ptr++; sc->cpu_cx_count++; continue; case ACPI_STATE_C2: sc->cpu_non_c3 = i; break; case ACPI_STATE_C3: default: if ((cpu_quirks & CPU_QUIRK_NO_C3) != 0) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: C3[%d] not available.\n", device_get_unit(sc->cpu_dev), i)); continue; } break; } #ifdef notyet /* Free up any previous register. */ if (cx_ptr->p_lvlx != NULL) { bus_release_resource(sc->cpu_dev, 0, 0, cx_ptr->p_lvlx); cx_ptr->p_lvlx = NULL; } #endif /* Allocate the control register for C2 or C3. */ cx_ptr->rid = sc->cpu_parent->cpux_next_rid; acpi_PkgGas(sc->cpu_dev, pkg, 0, &cx_ptr->res_type, &cx_ptr->rid, &cx_ptr->p_lvlx, RF_SHAREABLE); if (cx_ptr->p_lvlx) { sc->cpu_parent->cpux_next_rid++; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: Got C%d - %d latency\n", device_get_unit(sc->cpu_dev), cx_ptr->type, cx_ptr->trans_lat)); cx_ptr++; sc->cpu_cx_count++; } } AcpiOsFree(buf.Pointer); return (0); }
static int pst_attach(device_t dev) { struct pst_softc *psc = device_get_softc(dev); struct i2o_get_param_reply *reply; struct i2o_device_identity *ident; int lun = device_get_unit(dev); int8_t name [32]; if (!(reply = iop_get_util_params(psc->iop, psc->lct->local_tid, I2O_PARAMS_OPERATION_FIELD_GET, I2O_BSA_DEVICE_INFO_GROUP_NO))) return ENODEV; if (!(psc->info = (struct i2o_bsa_device *) malloc(sizeof(struct i2o_bsa_device), M_PSTRAID, M_NOWAIT))) { contigfree(reply, PAGE_SIZE, M_PSTIOP); return ENOMEM; } bcopy(reply->result, psc->info, sizeof(struct i2o_bsa_device)); contigfree(reply, PAGE_SIZE, M_PSTIOP); if (!(reply = iop_get_util_params(psc->iop, psc->lct->local_tid, I2O_PARAMS_OPERATION_FIELD_GET, I2O_UTIL_DEVICE_IDENTITY_GROUP_NO))) return ENODEV; ident = (struct i2o_device_identity *)reply->result; #ifdef PSTDEBUG printf("pst: vendor=<%.16s> product=<%.16s>\n", ident->vendor, ident->product); printf("pst: description=<%.16s> revision=<%.8s>\n", ident->description, ident->revision); printf("pst: capacity=%lld blocksize=%d\n", psc->info->capacity, psc->info->block_size); #endif bpack(ident->vendor, ident->vendor, 16); bpack(ident->product, ident->product, 16); sprintf(name, "%s %s", ident->vendor, ident->product); contigfree(reply, PAGE_SIZE, M_PSTIOP); bioq_init(&psc->queue); psc->disk = disk_alloc(); psc->disk->d_name = "pst"; psc->disk->d_strategy = pststrategy; psc->disk->d_maxsize = 64 * 1024; /*I2O_SGL_MAX_SEGS * PAGE_SIZE;*/ psc->disk->d_drv1 = psc; psc->disk->d_unit = lun; psc->disk->d_sectorsize = psc->info->block_size; psc->disk->d_mediasize = psc->info->capacity; psc->disk->d_fwsectors = 63; psc->disk->d_fwheads = 255; disk_create(psc->disk, DISK_VERSION); printf("pst%d: %lluMB <%.40s> [%lld/%d/%d] on %.16s\n", lun, (unsigned long long)psc->info->capacity / (1024 * 1024), name, psc->info->capacity/(512*255*63), 255, 63, device_get_nameunit(psc->iop->dev)); EVENTHANDLER_REGISTER(shutdown_post_sync, pst_shutdown, dev, SHUTDOWN_PRI_FIRST); return 0; }
static int rp_probe(device_t dev) { int unit; CONTROLLER_t *controller; int num_aiops; CONTROLLER_t *ctlp; int retval; /* * We have no PnP RocketPort cards. * (At least according to LINT) */ if (isa_get_logicalid(dev) != 0) return (ENXIO); /* We need IO port resource to configure an ISA device. */ if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 0) return (ENXIO); unit = device_get_unit(dev); if (unit >= 4) { device_printf(dev, "rpprobe: unit number %d invalid.\n", unit); return (ENXIO); } device_printf(dev, "probing for RocketPort(ISA) unit %d.\n", unit); ctlp = device_get_softc(dev); bzero(ctlp, sizeof(*ctlp)); ctlp->dev = dev; ctlp->aiop2rid = rp_isa_aiop2rid; ctlp->aiop2off = rp_isa_aiop2off; ctlp->ctlmask = rp_isa_ctlmask; /* The IO ports of AIOPs for an ISA controller are discrete. */ ctlp->io_num = 1; ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); if (ctlp->io_rid == NULL || ctlp->io == NULL) { device_printf(dev, "rp_attach: Out of memory.\n"); retval = ENOMEM; goto nogo; } ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT | M_ZERO); if (ctlp->bus_ctlp == NULL) { device_printf(dev, "rp_attach: Out of memory.\n"); retval = ENOMEM; goto nogo; } ctlp->io_rid[0] = 0; if (rp_controller != NULL) { controller = rp_controller; ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x40, RF_ACTIVE); } else { controller = rp_controller = ctlp; ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x44, RF_ACTIVE); } if (ctlp->io[0] == NULL) { device_printf(dev, "rp_attach: Resource not available.\n"); retval = ENXIO; goto nogo; } num_aiops = sInitController(ctlp, controller, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0); if (num_aiops <= 0) { device_printf(dev, "board%d init failed.\n", unit); retval = ENXIO; goto nogo; } if (rp_controller == NULL) rp_controller = controller; rp_nisadevs++; device_set_desc(dev, "RocketPort ISA"); return (0); nogo: rp_isareleaseresource(ctlp); return (retval); }
static int hwpstate_probe(device_t dev) { struct hwpstate_softc *sc; device_t perf_dev; uint64_t msr; int error, type; /* * Only hwpstate0. * It goes well with acpi_throttle. */ if (device_get_unit(dev) != 0) return (ENXIO); sc = device_get_softc(dev); sc->dev = dev; /* * Check if acpi_perf has INFO only flag. */ perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1); error = TRUE; if (perf_dev && device_is_attached(perf_dev)) { error = CPUFREQ_DRV_TYPE(perf_dev, &type); if (error == 0) { if ((type & CPUFREQ_FLAG_INFO_ONLY) == 0) { /* * If acpi_perf doesn't have INFO_ONLY flag, * it will take care of pstate transitions. */ HWPSTATE_DEBUG(dev, "acpi_perf will take care of pstate transitions.\n"); return (ENXIO); } else { /* * If acpi_perf has INFO_ONLY flag, (_PCT has FFixedHW) * we can get _PSS info from acpi_perf * without going into ACPI. */ HWPSTATE_DEBUG(dev, "going to fetch info from acpi_perf\n"); error = hwpstate_get_info_from_acpi_perf(dev, perf_dev); } } } if (error == 0) { /* * Now we get _PSS info from acpi_perf without error. * Let's check it. */ msr = rdmsr(MSR_AMD_10H_11H_LIMIT); if (sc->cfnum != 1 + AMD_10H_11H_GET_PSTATE_MAX_VAL(msr)) { HWPSTATE_DEBUG(dev, "msr and acpi _PSS count mismatch.\n"); error = TRUE; } } /* * If we cannot get info from acpi_perf, * Let's get info from MSRs. */ if (error) error = hwpstate_get_info_from_msr(dev); if (error) return (error); device_set_desc(dev, "Cool`n'Quiet 2.0"); return (0); }
/* * Function name: tw_osli_cam_attach * Description: Attaches the driver to CAM. * * Input: sc -- ptr to OSL internal ctlr context * Output: None * Return value: 0 -- success * non-zero-- failure */ TW_INT32 tw_osli_cam_attach(struct twa_softc *sc) { struct cam_devq *devq; tw_osli_dbg_dprintf(3, sc, "entered"); /* * Create the device queue for our SIM. */ if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_IOS)) == NULL) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2100, "Failed to create SIM device queue", ENOMEM); return(ENOMEM); } /* * Create a SIM entry. Though we can support TW_OSLI_MAX_NUM_REQUESTS * simultaneous requests, we claim to be able to handle only * TW_OSLI_MAX_NUM_IOS (two less), so that we always have a request * packet available to service ioctls and AENs. */ tw_osli_dbg_dprintf(3, sc, "Calling cam_sim_alloc"); sc->sim = cam_sim_alloc(twa_action, twa_poll, "twa", sc, device_get_unit(sc->bus_dev), sc->sim_lock, TW_OSLI_MAX_NUM_IOS, 1, devq); if (sc->sim == NULL) { cam_simq_free(devq); tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2101, "Failed to create a SIM entry", ENOMEM); return(ENOMEM); } /* * Register the bus. */ tw_osli_dbg_dprintf(3, sc, "Calling xpt_bus_register"); mtx_lock(sc->sim_lock); if (xpt_bus_register(sc->sim, sc->bus_dev, 0) != CAM_SUCCESS) { cam_sim_free(sc->sim, TRUE); sc->sim = NULL; /* so cam_detach will not try to free it */ tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2102, "Failed to register the bus", ENXIO); mtx_unlock(sc->sim_lock); return(ENXIO); } tw_osli_dbg_dprintf(3, sc, "Calling xpt_create_path"); if (xpt_create_path(&sc->path, NULL, cam_sim_path(sc->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path (sc->sim)); /* Passing TRUE to cam_sim_free will free the devq as well. */ cam_sim_free(sc->sim, TRUE); tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2103, "Failed to create path", ENXIO); mtx_unlock(sc->sim_lock); return(ENXIO); } mtx_unlock(sc->sim_lock); tw_osli_dbg_dprintf(3, sc, "exiting"); return(0); }
static void bcm_fb_init(void *arg) { volatile struct bcm_fb_config *fb_config; struct bcmsc_softc *sc; struct fb_info *info; phandle_t node; pcell_t cell; device_t mbox; device_t fbd; int err = 0; sc = arg; fb_config = sc->fb_config; node = ofw_bus_get_node(sc->dev); fb_config->xres = 0; fb_config->yres = 0; fb_config->bpp = 0; fb_config->vxres = 0; fb_config->vyres = 0; fb_config->xoffset = 0; fb_config->yoffset = 0; fb_config->base = 0; fb_config->pitch = 0; fb_config->screen_size = 0; if ((OF_getprop(node, "broadcom,width", &cell, sizeof(cell))) > 0) fb_config->xres = (int)fdt32_to_cpu(cell); if (fb_config->xres == 0) fb_config->xres = FB_WIDTH; if ((OF_getprop(node, "broadcom,height", &cell, sizeof(cell))) > 0) fb_config->yres = (uint32_t)fdt32_to_cpu(cell); if (fb_config->yres == 0) fb_config->yres = FB_HEIGHT; if ((OF_getprop(node, "broadcom,depth", &cell, sizeof(cell))) > 0) fb_config->bpp = (uint32_t)fdt32_to_cpu(cell); if (fb_config->bpp == 0) fb_config->bpp = FB_DEPTH; bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); mbox = devclass_get_device(devclass_find("mbox"), 0); if (mbox) { MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_FB, sc->fb_config_phys); MBOX_READ(mbox, BCM2835_MBOX_CHAN_FB, &err); } bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_POSTREAD); if (fb_config->base != 0) { device_printf(sc->dev, "%dx%d(%dx%d@%d,%d) %dbpp\n", fb_config->xres, fb_config->yres, fb_config->vxres, fb_config->vyres, fb_config->xoffset, fb_config->yoffset, fb_config->bpp); device_printf(sc->dev, "pitch %d, base 0x%08x, screen_size %d\n", fb_config->pitch, fb_config->base, fb_config->screen_size); info = malloc(sizeof(struct fb_info), M_DEVBUF, M_WAITOK | M_ZERO); info->fb_name = device_get_nameunit(sc->dev); info->fb_vbase = (intptr_t)pmap_mapdev(fb_config->base, fb_config->screen_size); info->fb_pbase = fb_config->base; info->fb_size = fb_config->screen_size; info->fb_bpp = info->fb_depth = fb_config->bpp; info->fb_stride = fb_config->pitch; info->fb_width = fb_config->xres; info->fb_height = fb_config->yres; sc->info = info; fbd = device_add_child(sc->dev, "fbd", device_get_unit(sc->dev)); if (fbd == NULL) { device_printf(sc->dev, "Failed to add fbd child\n"); return; } if (device_probe_and_attach(fbd) != 0) { device_printf(sc->dev, "Failed to attach fbd device\n"); return; } } else { device_printf(sc->dev, "Failed to set framebuffer info\n"); return; } config_intrhook_disestablish(&sc->init_hook); }
/* * Attach the device. Initialize the card. */ int siattach(device_t dev) { int unit; struct si_softc *sc; struct si_port *pp; struct tty *tp; volatile struct si_channel *ccbp; volatile struct si_reg *regp; volatile caddr_t maddr; struct si_module *modp; int nmodule, nport, x, y; int uart_type; sc = device_get_softc(dev); unit = device_get_unit(dev); sc->sc_typename = si_type[sc->sc_type]; if (si_numunits < unit + 1) si_numunits = unit + 1; DPRINT((0, DBG_AUTOBOOT, "si%d: siattach\n", unit)); #ifdef POLL if (si_pollrate == 0) { si_pollrate = POLLHZ; /* in addition to irq */ #ifdef REALPOLL si_realpoll = 1; /* scan always */ #endif } #endif DPRINT((0, DBG_AUTOBOOT, "si%d: type: %s paddr: %x maddr: %x\n", unit, sc->sc_typename, sc->sc_paddr, sc->sc_maddr)); sc->sc_ports = NULL; /* mark as uninitialised */ maddr = sc->sc_maddr; /* Stop the CPU first so it won't stomp around while we load */ switch (sc->sc_type) { #ifdef DEV_EISA case SIEISA: outb(sc->sc_iobase + 2, sc->sc_irq << 4); #endif break; case SIPCI: *(maddr+SIPCIRESET) = 0; break; case SIJETPCI: /* fall through to JET ISA */ case SIJETISA: *(maddr+SIJETCONFIG) = 0; break; case SIHOST2: *(maddr+SIPLRESET) = 0; break; case SIHOST: *(maddr+SIRESET) = 0; break; default: /* this should never happen */ printf("si%d: unsupported configuration\n", unit); return EINVAL; break; } /* OK, now lets download the download code */ if (SI_ISJET(sc->sc_type)) { DPRINT((0, DBG_DOWNLOAD, "si%d: jet_download: nbytes %d\n", unit, si3_t225_dsize)); si_bcopy(si3_t225_download, maddr + si3_t225_downloadaddr, si3_t225_dsize); DPRINT((0, DBG_DOWNLOAD, "si%d: jet_bootstrap: nbytes %d -> %x\n", unit, si3_t225_bsize, si3_t225_bootloadaddr)); si_bcopy(si3_t225_bootstrap, maddr + si3_t225_bootloadaddr, si3_t225_bsize); } else { DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n", unit, si2_z280_dsize)); si_bcopy(si2_z280_download, maddr + si2_z280_downloadaddr, si2_z280_dsize); } /* Now start the CPU */ switch (sc->sc_type) { #ifdef DEV_EISA case SIEISA: /* modify the download code to tell it that it's on an EISA */ *(maddr + 0x42) = 1; outb(sc->sc_iobase + 2, (sc->sc_irq << 4) | 4); (void)inb(sc->sc_iobase + 3); /* reset interrupt */ break; #endif case SIPCI: /* modify the download code to tell it that it's on a PCI */ *(maddr+0x42) = 1; *(maddr+SIPCIRESET) = 1; *(maddr+SIPCIINTCL) = 0; break; case SIJETPCI: *(maddr+SIJETRESET) = 0; *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN; break; case SIJETISA: *(maddr+SIJETRESET) = 0; switch (sc->sc_irq) { case 9: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0x90; break; case 10: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xa0; break; case 11: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xb0; break; case 12: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xc0; break; case 15: *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xf0; break; } break; case SIHOST: *(maddr+SIRESET_CL) = 0; *(maddr+SIINTCL_CL) = 0; break; case SIHOST2: *(maddr+SIPLRESET) = 0x10; switch (sc->sc_irq) { case 11: *(maddr+SIPLIRQ11) = 0x10; break; case 12: *(maddr+SIPLIRQ12) = 0x10; break; case 15: *(maddr+SIPLIRQ15) = 0x10; break; } *(maddr+SIPLIRQCLR) = 0x10; break; default: /* this should _REALLY_ never happen */ printf("si%d: Uh, it was supported a second ago...\n", unit); return EINVAL; } DELAY(1000000); /* wait around for a second */ regp = (struct si_reg *)maddr; y = 0; /* wait max of 5 sec for init OK */ while (regp->initstat == 0 && y++ < 10) { DELAY(500000); } switch (regp->initstat) { case 0: printf("si%d: startup timeout - aborting\n", unit); sc->sc_type = SIEMPTY; return EINVAL; case 1: if (SI_ISJET(sc->sc_type)) { /* set throttle to 100 times per second */ regp->int_count = JET_INT_COUNT; /* rx_intr_count is a NOP in Jet */ } else { /* set throttle to 125 times per second */ regp->int_count = INT_COUNT; /* rx intr max of 25 times per second */ regp->rx_int_count = RXINT_COUNT; } regp->int_pending = 0; /* no intr pending */ regp->int_scounter = 0; /* reset counter */ break; case 0xff: /* * No modules found, so give up on this one. */ printf("si%d: %s - no ports found\n", unit, si_type[sc->sc_type]); return 0; default: printf("si%d: download code version error - initstat %x\n", unit, regp->initstat); return EINVAL; } /* * First time around the ports just count them in order * to allocate some memory. */ nport = 0; modp = (struct si_module *)(maddr + 0x80); for (;;) { DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp)); switch (modp->sm_type) { case TA4: DPRINT((0, DBG_DOWNLOAD, "si%d: Found old TA4 module, 4 ports\n", unit)); x = 4; break; case TA8: DPRINT((0, DBG_DOWNLOAD, "si%d: Found old TA8 module, 8 ports\n", unit)); x = 8; break; case TA4_ASIC: DPRINT((0, DBG_DOWNLOAD, "si%d: Found ASIC TA4 module, 4 ports\n", unit)); x = 4; break; case TA8_ASIC: DPRINT((0, DBG_DOWNLOAD, "si%d: Found ASIC TA8 module, 8 ports\n", unit)); x = 8; break; case MTA: DPRINT((0, DBG_DOWNLOAD, "si%d: Found CD1400 module, 8 ports\n", unit)); x = 8; break; case SXDC: DPRINT((0, DBG_DOWNLOAD, "si%d: Found SXDC module, 8 ports\n", unit)); x = 8; break; default: printf("si%d: unknown module type %d\n", unit, modp->sm_type); goto try_next; } /* this was limited in firmware and is also a driver issue */ if ((nport + x) > SI_MAXPORTPERCARD) { printf("si%d: extra ports ignored\n", unit); goto try_next; } nport += x; si_Nports += x; si_Nmodules++; try_next: if (modp->sm_next == 0) break; modp = (struct si_module *) (maddr + (unsigned)(modp->sm_next & 0x7fff)); } sc->sc_ports = (struct si_port *)malloc(sizeof(struct si_port) * nport, M_DEVBUF, M_NOWAIT | M_ZERO); if (sc->sc_ports == 0) { printf("si%d: fail to malloc memory for port structs\n", unit); return EINVAL; } sc->sc_nport = nport; /* * Scan round the ports again, this time initialising. */ pp = sc->sc_ports; nmodule = 0; modp = (struct si_module *)(maddr + 0x80); uart_type = 1000; /* arbitary, > uchar_max */ for (;;) { switch (modp->sm_type) { case TA4: nport = 4; break; case TA8: nport = 8; break; case TA4_ASIC: nport = 4; break; case TA8_ASIC: nport = 8; break; case MTA: nport = 8; break; case SXDC: nport = 8; break; default: goto try_next2; } nmodule++; ccbp = (struct si_channel *)((char *)modp + 0x100); if (uart_type == 1000) uart_type = ccbp->type; else if (uart_type != ccbp->type) printf("si%d: Warning: module %d mismatch! (%d%s != %d%s)\n", unit, nmodule, ccbp->type, si_modulename(sc->sc_type, ccbp->type), uart_type, si_modulename(sc->sc_type, uart_type)); for (x = 0; x < nport; x++, pp++, ccbp++) { pp->sp_ccb = ccbp; /* save the address */ pp->sp_pend = IDLE_CLOSE; pp->sp_state = 0; /* internal flag */ #ifdef SI_DEBUG sprintf(pp->sp_name, "si%r%r", unit, (int)(pp - sc->sc_ports)); #endif tp = pp->sp_tty = tty_alloc_mutex(&si_tty_class, pp, &Giant); tty_makedev(tp, NULL, "A%r%r", unit, (int)(pp - sc->sc_ports)); } try_next2: if (modp->sm_next == 0) { printf("si%d: card: %s, ports: %d, modules: %d, type: %d%s\n", unit, sc->sc_typename, sc->sc_nport, nmodule, uart_type, si_modulename(sc->sc_type, uart_type)); break; } modp = (struct si_module *) (maddr + (unsigned)(modp->sm_next & 0x7fff)); } if (unit == 0) make_dev(&si_Scdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "si_control"); return (0); }
static int tga_attach(device_t dev) { gfb_softc_t sc; int unit, error, rid; error = 0; unit = device_get_unit(dev); sc = device_get_softc(dev); sc->driver_name = TGA_DRIVER_NAME; switch(pci_get_device(dev)) { case DEC_DEVICEID_TGA2: sc->model = 1; sc->type = KD_TGA2; break; case DEC_DEVICEID_TGA: sc->model = 0; sc->type = KD_TGA; break; default: device_printf(dev, "Unrecognized TGA type\n"); goto fail; } if((error = pcigfb_attach(dev))) { goto fail; } sc->regs = sc->bhandle + TGA_MEM_CREGS; error = bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, tga_intr, sc, &sc->intrhand); if(error) { device_printf(dev, "couldn't set up irq\n"); goto fail; } switch(sc->rev) { case 0x1: case 0x2: case 0x3: device_printf(dev, "TGA (21030) step %c\n", 'A' + sc->rev - 1); break; case 0x20: device_printf(dev, "TGA2 (21130) abstract software model\n"); break; case 0x21: case 0x22: device_printf(dev, "TGA2 (21130) pass %d\n", sc->rev - 0x20); break; default: device_printf(dev, "Unknown stepping (0x%x)\n", sc->rev); break; } #ifdef FB_INSTALL_CDEV sc->cdevsw = &tga_cdevsw; sc->devt = make_dev(sc->cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, "tga%x", unit); #endif /* FB_INSTALL_CDEV */ goto done; fail: if(sc->intrhand != NULL) { bus_teardown_intr(dev, sc->irq, sc->intrhand); sc->intrhand = NULL; } if(sc->irq != NULL) { rid = 0x0; bus_release_resource(dev, SYS_RES_IRQ, rid, sc->irq); sc->irq = NULL; } if(sc->res != NULL) { rid = GFB_MEM_BASE_RID; bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->res); sc->res = NULL; } error = ENXIO; done: return(error); }
static int fwe_attach(device_t dev) { struct fwe_softc *fwe; struct ifnet *ifp; int unit, s; u_char eaddr[6]; struct fw_eui64 *eui; fwe = ((struct fwe_softc *)device_get_softc(dev)); unit = device_get_unit(dev); bzero(fwe, sizeof(struct fwe_softc)); mtx_init(&fwe->mtx, "fwe", NULL, MTX_DEF); /* XXX */ fwe->stream_ch = stream_ch; fwe->dma_ch = -1; fwe->fd.fc = device_get_ivars(dev); if (tx_speed < 0) tx_speed = fwe->fd.fc->speed; fwe->fd.dev = dev; fwe->fd.post_explore = NULL; fwe->eth_softc.fwe = fwe; fwe->pkt_hdr.mode.stream.tcode = FWTCODE_STREAM; fwe->pkt_hdr.mode.stream.sy = 0; fwe->pkt_hdr.mode.stream.chtag = fwe->stream_ch; /* generate fake MAC address: first and last 3bytes from eui64 */ #define LOCAL (0x02) #define GROUP (0x01) eui = &fwe->fd.fc->eui; eaddr[0] = (FW_EUI64_BYTE(eui, 0) | LOCAL) & ~GROUP; eaddr[1] = FW_EUI64_BYTE(eui, 1); eaddr[2] = FW_EUI64_BYTE(eui, 2); eaddr[3] = FW_EUI64_BYTE(eui, 5); eaddr[4] = FW_EUI64_BYTE(eui, 6); eaddr[5] = FW_EUI64_BYTE(eui, 7); printf("if_fwe%d: Fake Ethernet address: " "%02x:%02x:%02x:%02x:%02x:%02x\n", unit, eaddr[0], eaddr[1], eaddr[2], eaddr[3], eaddr[4], eaddr[5]); /* fill the rest and attach interface */ ifp = fwe->eth_softc.ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); return (ENOSPC); } ifp->if_softc = &fwe->eth_softc; if_initname(ifp, device_get_name(dev), unit); ifp->if_init = fwe_init; ifp->if_start = fwe_start; ifp->if_ioctl = fwe_ioctl; ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE; s = splimp(); ether_ifattach(ifp, eaddr); splx(s); /* Tell the upper layer(s) we support long frames. */ ifp->if_hdrlen = sizeof(struct ether_vlan_header); ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_POLLING; ifp->if_capenable |= IFCAP_VLAN_MTU; FWEDEBUG(ifp, "interface created\n"); return 0; }
static int at91_mci_attach(device_t dev) { struct at91_mci_softc *sc = device_get_softc(dev); struct sysctl_ctx_list *sctx; struct sysctl_oid *soid; device_t child; int err, i; sctx = device_get_sysctl_ctx(dev); soid = device_get_sysctl_tree(dev); sc->dev = dev; sc->sc_cap = 0; if (at91_is_rm92()) sc->sc_cap |= CAP_NEEDS_BYTESWAP; /* * MCI1 Rev 2 controllers need some workarounds, flag if so. */ if (at91_mci_is_mci1rev2xx()) sc->sc_cap |= CAP_MCI1_REV2XX; err = at91_mci_activate(dev); if (err) goto out; AT91_MCI_LOCK_INIT(sc); at91_mci_fini(dev); at91_mci_init(dev); /* * Allocate DMA tags and maps and bounce buffers. * * The parms in the tag_create call cause the dmamem_alloc call to * create each bounce buffer as a single contiguous buffer of BBSIZE * bytes aligned to a 4096 byte boundary. * * Do not use DMA_COHERENT for these buffers because that maps the * memory as non-cachable, which prevents cache line burst fills/writes, * which is something we need since we're trying to overlap the * byte-swapping with the DMA operations. */ err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, BBSIZE, 1, BBSIZE, 0, NULL, NULL, &sc->dmatag); if (err != 0) goto out; for (i = 0; i < BBCOUNT; ++i) { err = bus_dmamem_alloc(sc->dmatag, (void **)&sc->bbuf_vaddr[i], BUS_DMA_NOWAIT, &sc->bbuf_map[i]); if (err != 0) goto out; } /* * Activate the interrupt */ err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, at91_mci_intr, sc, &sc->intrhand); if (err) { AT91_MCI_LOCK_DESTROY(sc); goto out; } /* * Allow 4-wire to be initially set via #define. * Allow a device hint to override that. * Allow a sysctl to override that. */ #if defined(AT91_MCI_HAS_4WIRE) && AT91_MCI_HAS_4WIRE != 0 sc->has_4wire = 1; #endif resource_int_value(device_get_name(dev), device_get_unit(dev), "4wire", &sc->has_4wire); SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "4wire", CTLFLAG_RW, &sc->has_4wire, 0, "has 4 wire SD Card bus"); if (sc->has_4wire) sc->sc_cap |= CAP_HAS_4WIRE; sc->allow_overclock = AT91_MCI_ALLOW_OVERCLOCK; resource_int_value(device_get_name(dev), device_get_unit(dev), "allow_overclock", &sc->allow_overclock); SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "allow_overclock", CTLFLAG_RW, &sc->allow_overclock, 0, "Allow up to 30MHz clock for 25MHz request when next highest speed 15MHz or less."); /* * Our real min freq is master_clock/512, but upper driver layers are * going to set the min speed during card discovery, and the right speed * for that is 400kHz, so advertise a safe value just under that. * * For max speed, while the rm9200 manual says the max is 50mhz, it also * says it supports only the SD v1.0 spec, which means the real limit is * 25mhz. On the other hand, historical use has been to slightly violate * the standard by running the bus at 30MHz. For more information on * that, see the comments at the top of this file. */ sc->host.f_min = 375000; sc->host.f_max = at91_master_clock / 2; if (sc->host.f_max > 25000000) sc->host.f_max = 25000000; sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340; sc->host.caps = 0; if (sc->sc_cap & CAP_HAS_4WIRE) sc->host.caps |= MMC_CAP_4_BIT_DATA; child = device_add_child(dev, "mmc", 0); device_set_ivars(dev, &sc->host); err = bus_generic_attach(dev); out: if (err) at91_mci_deactivate(dev); return (err); }
static int iir_pci_attach(device_t dev) { struct gdt_softc *gdt; struct resource *io = NULL, *irq = NULL; int retries, rid, error = 0; void *ih; u_int8_t protocol; /* map DPMEM */ rid = PCI_DPMEM; io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (io == NULL) { device_printf(dev, "can't allocate register resources\n"); error = ENOMEM; goto err; } /* get IRQ */ rid = 0; irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | RF_SHAREABLE); if (irq == NULL) { device_printf(dev, "can't find IRQ value\n"); error = ENOMEM; goto err; } gdt = device_get_softc(dev); gdt->sc_init_level = 0; gdt->sc_dpmemt = rman_get_bustag(io); gdt->sc_dpmemh = rman_get_bushandle(io); gdt->sc_dpmembase = rman_get_start(io); gdt->sc_hanum = device_get_unit(dev); gdt->sc_bus = pci_get_bus(dev); gdt->sc_slot = pci_get_slot(dev); gdt->sc_vendor = pci_get_vendor(dev); gdt->sc_device = pci_get_device(dev); gdt->sc_subdevice = pci_get_subdevice(dev); gdt->sc_class = GDT_MPR; /* no FC ctr. if (gdt->sc_device >= GDT_PCI_PRODUCT_FC) gdt->sc_class |= GDT_FC; */ /* initialize RP controller */ /* check and reset interface area */ bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC, htole32(GDT_MPR_MAGIC)); if (bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC) != htole32(GDT_MPR_MAGIC)) { kprintf("cannot access DPMEM at 0x%jx (shadowed?)\n", (uintmax_t)gdt->sc_dpmembase); error = ENXIO; goto err; } bus_space_set_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_I960_SZ, htole32(0), GDT_MPR_SZ >> 2); /* Disable everything */ bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN, bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN) | 4); bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff); bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, 0); bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_CMD_INDEX, 0); bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO, htole32(gdt->sc_dpmembase)); bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX, 0xff); bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS) != 0xff) { if (--retries == 0) { kprintf("DEINIT failed\n"); error = ENXIO; goto err; } DELAY(1); } protocol = (uint8_t)le32toh(bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO)); bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, 0); if (protocol != GDT_PROTOCOL_VERSION) { kprintf("unsupported protocol %d\n", protocol); error = ENXIO; goto err; } /* special commnd to controller BIOS */ bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO, htole32(0)); bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), htole32(0)); bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), htole32(1)); bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), htole32(0)); bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX, 0xfe); bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS) != 0xfe) { if (--retries == 0) { kprintf("initialization error\n"); error = ENXIO; goto err; } DELAY(1); } bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, 0); gdt->sc_ic_all_size = GDT_MPR_SZ; gdt->sc_copy_cmd = gdt_mpr_copy_cmd; gdt->sc_get_status = gdt_mpr_get_status; gdt->sc_intr = gdt_mpr_intr; gdt->sc_release_event = gdt_mpr_release_event; gdt->sc_set_sema0 = gdt_mpr_set_sema0; gdt->sc_test_busy = gdt_mpr_test_busy; /* Allocate a dmatag representing the capabilities of this attachment */ /* XXX Should be a child of the PCI bus dma tag */ if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, /*nsegments*/GDT_MAXSG, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, &gdt->sc_parent_dmat) != 0) { error = ENXIO; goto err; } gdt->sc_init_level++; if (iir_init(gdt) != 0) { iir_free(gdt); error = ENXIO; goto err; } /* Register with the XPT */ iir_attach(gdt); /* associate interrupt handler */ error = bus_setup_intr(dev, irq, 0, iir_intr, gdt, &ih, NULL); if (error) { device_printf(dev, "Unable to register interrupt handler\n"); error = ENXIO; goto err; } gdt_pci_enable_intr(gdt); return (0); err: if (irq) bus_release_resource( dev, SYS_RES_IRQ, 0, irq ); /* if (io) bus_release_resource( dev, SYS_RES_MEMORY, rid, io ); */ return (error); }
/* * icintr() */ static void icintr (device_t dev, int event, char *ptr) { struct ic_softc *sc = (struct ic_softc *)device_get_softc(dev); int unit = device_get_unit(dev); int s, len; struct mbuf *top; s = splhigh(); switch (event) { case INTR_GENERAL: case INTR_START: sc->ic_cp = sc->ic_ifbuf; sc->ic_xfercnt = 0; break; case INTR_STOP: /* if any error occured during transfert, * drop the packet */ if (sc->ic_iferrs) goto err; if ((len = sc->ic_xfercnt) == 0) break; /* ignore */ if (len <= ICHDRLEN) goto err; if (IF_QFULL(&ipintrq)) { IF_DROP(&ipintrq); break; } len -= ICHDRLEN; sc->ic_if.if_ipackets ++; sc->ic_if.if_ibytes += len; if (sc->ic_if.if_bpf) bpf_tap(&sc->ic_if, sc->ic_ifbuf, len + ICHDRLEN); top = m_devget(sc->ic_ifbuf + ICHDRLEN, len, 0, &sc->ic_if, 0); if (top) { IF_ENQUEUE(&ipintrq, top); schednetisr(NETISR_IP); } break; err: printf("ic%d: errors (%d)!\n", unit, sc->ic_iferrs); sc->ic_iferrs = 0; /* reset error count */ sc->ic_if.if_ierrors ++; break; case INTR_RECEIVE: if (sc->ic_xfercnt >= sc->ic_if.if_mtu+ICHDRLEN) { sc->ic_iferrs ++; } else { *sc->ic_cp++ = *ptr; sc->ic_xfercnt ++; } break; case INTR_NOACK: /* xfer terminated by master */ break; case INTR_TRANSMIT: *ptr = 0xff; /* XXX */ break; case INTR_ERROR: sc->ic_iferrs ++; break; default: panic("%s: unknown event (%d)!", __FUNCTION__, event); } splx(s); return; }
/* * Check if the device can be found at the port given * and if so, set it up ready for further work * as an argument, takes the isa_device structure from * autoconf.c */ static int aha_isa_probe(device_t dev) { /* * find unit and check we have that many defined */ struct aha_softc **sc = device_get_softc(dev); struct aha_softc *aha; int port_index; int max_port_index; int error; u_long port_start, port_count; struct resource *port_res; int port_rid; int drq; int irq; aha = NULL; /* Check isapnp ids */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, aha_ids) == ENXIO) return (ENXIO); error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &port_start, &port_count); if (error != 0) port_start = 0; /* * Bound our board search if the user has * specified an exact port. */ aha_find_probe_range(port_start, &port_index, &max_port_index); if (port_index < 0) return ENXIO; /* Attempt to find an adapter */ for (;port_index <= max_port_index; port_index++) { config_data_t config_data; u_int ioport; int error; ioport = aha_iop_from_bio(port_index); error = bus_set_resource(dev, SYS_RES_IOPORT, 0, ioport, AHA_NREGS); if (error) return error; port_rid = 0; port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, 0, ~0, AHA_NREGS, RF_ACTIVE); if (!port_res) continue; /* Allocate a softc for use during probing */ aha = aha_alloc(device_get_unit(dev), rman_get_bustag(port_res), rman_get_bushandle(port_res)); if (aha == NULL) { bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); break; } /* See if there is really a card present */ if (aha_probe(aha) || aha_fetch_adapter_info(aha)) { aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); continue; } /* * Determine our IRQ, and DMA settings and * export them to the configuration system. */ error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, (u_int8_t*)&config_data, sizeof(config_data), DEFAULT_CMD_TIMEOUT); if (error != 0) { printf("aha_isa_probe: Could not determine IRQ or DMA " "settings for adapter at 0x%x. Failing probe\n", ioport); aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); continue; } bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); switch (config_data.dma_chan) { case DMA_CHAN_5: drq = 5; break; case DMA_CHAN_6: drq = 6; break; case DMA_CHAN_7: drq = 7; break; default: printf("aha_isa_probe: Invalid DMA setting " "detected for adapter at 0x%x. " "Failing probe\n", ioport); return (ENXIO); } error = bus_set_resource(dev, SYS_RES_DRQ, 0, drq, 1); if (error) return error; irq = ffs(config_data.irq) + 8; error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); if (error) return error; *sc = aha; aha_unit++; return (0); } return (ENXIO); }
/*---------------------------------------------------------------------------* * isic_probe_avma1 - probe for AVM A1 and compatibles *---------------------------------------------------------------------------*/ int isic_probe_avma1(device_t dev) { size_t unit = device_get_unit(dev); /* get unit */ struct l1_softc *sc = 0; /* pointer to softc */ void *ih = 0; /* dummy */ bus_space_tag_t t; /* bus things */ bus_space_handle_t h; u_char savebyte; u_char byte; /* check max unit range */ if(unit >= ISIC_MAXUNIT) { printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for AVM A1/Fritz!\n", unit, unit); return(ENXIO); } sc = &l1_sc[unit]; /* get pointer to softc */ sc->sc_unit = unit; /* set unit */ /* see if an io base was supplied */ if(!(sc->sc_resources.io_base[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_resources.io_rid[0], 0ul, ~0ul, 1, RF_ACTIVE))) { printf("isic%d: Could not get iobase for AVM A1/Fritz!\n", unit); return(ENXIO); } /* set io base */ sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); /* release io base */ bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0], sc->sc_resources.io_base[0]); switch(sc->sc_port) { case 0x200: case 0x240: case 0x300: case 0x340: break; default: printf("isic%d: Error, invalid iobase 0x%x specified for AVM A1/Fritz!\n", unit, sc->sc_port); return(ENXIO); break; } if(isic_alloc_port(dev, 0, sc->sc_port+AVM_CONF_REG, 0x20)) return(ENXIO); if(isic_alloc_port(dev, 1, sc->sc_port+AVM_ISAC_R_OFFS, 0x20)) return(ENXIO); if(isic_alloc_port(dev, 2, sc->sc_port+AVM_HSCXA_R_OFFS, 0x20)) return(ENXIO); if(isic_alloc_port(dev, 3, sc->sc_port+AVM_HSCXB_R_OFFS, 0x20)) return(ENXIO); if(isic_alloc_port(dev, 4, sc->sc_port+AVM_ISAC_F_OFFS, 0x20)) return(ENXIO); if(isic_alloc_port(dev, 5, sc->sc_port+AVM_HSCXA_F_OFFS, 0x20)) return(ENXIO); if(isic_alloc_port(dev, 6, sc->sc_port+AVM_HSCXB_F_OFFS, 0x20)) return(ENXIO); /* get our irq */ if(!(sc->sc_resources.irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_resources.irq_rid, 0ul, ~0ul, 1, RF_ACTIVE))) { printf("isic%d: Could not get an irq for AVM A1/Fritz!\n",unit); isic_detach_common(dev); return ENXIO; } /* get the irq number */ sc->sc_irq = rman_get_start(sc->sc_resources.irq); /* register interupt routine */ bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, (void(*)(void *))(isicintr), sc, &ih); /* check IRQ validity */ switch(sc->sc_irq) { case 3: case 4: case 5: case 6: case 7: case 8: case 10: case 11: case 12: case 13: case 14: case 15: break; default: printf("isic%d: Error, invalid IRQ [%d] specified for AVM A1/Fritz!\n", unit, sc->sc_irq); isic_detach_common(dev); return(ENXIO); break; } sc->clearirq = NULL; sc->readreg = avma1_read_reg; sc->writereg = avma1_write_reg; sc->readfifo = avma1_read_fifo; sc->writefifo = avma1_write_fifo; /* setup card type */ sc->sc_cardtyp = CARD_TYPEP_AVMA1; /* setup IOM bus type */ sc->sc_bustyp = BUS_TYPE_IOM2; sc->sc_ipac = 0; sc->sc_bfifolen = HSCX_FIFO_LEN; /* * Read HSCX A/B VSTR. * Expected value for AVM A1 is 0x04 or 0x05 and for the * AVM Fritz!Card is 0x05 in the least significant bits. */ if( (((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) && ((HSCX_READ(0, H_VSTR) & 0xf) != 0x4)) || (((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) && ((HSCX_READ(1, H_VSTR) & 0xf) != 0x4)) ) { printf("isic%d: HSCX VSTR test failed for AVM A1/Fritz\n", unit); printf("isic%d: HSC0: VSTR: %#x\n", unit, HSCX_READ(0, H_VSTR)); printf("isic%d: HSC1: VSTR: %#x\n", unit, HSCX_READ(1, H_VSTR)); return(ENXIO); } /* AVM A1 or Fritz! control register bits: */ /* read write */ /* 0x01 hscx irq* RESET */ /* 0x02 isac irq* clear counter1 */ /* 0x04 counter irq* clear counter2 */ /* 0x08 always 0 irq enable */ /* 0x10 read test bit set test bit */ /* 0x20 always 0 unused */ /* * XXX the following test may be destructive, to prevent the * worst case, we save the byte first, and in case the test * fails, we write back the saved byte ..... */ t = rman_get_bustag(sc->sc_resources.io_base[0]); h = rman_get_bushandle(sc->sc_resources.io_base[0]); savebyte = bus_space_read_1(t, h, 0); /* write low to test bit */ bus_space_write_1(t, h, 0, 0x00); /* test bit and next higher and lower bit must be 0 */ if((byte = bus_space_read_1(t, h, 0) & 0x38) != 0x00) { printf("isic%d: Error, probe-1 failed, 0x%02x should be 0x00 for AVM A1/Fritz!\n", unit, byte); bus_space_write_1(t, h, 0, savebyte); return(ENXIO); } /* write high to test bit */ bus_space_write_1(t, h, 0, 0x10); /* test bit must be high, next higher and lower bit must be 0 */ if((byte = bus_space_read_1(t, h, 0) & 0x38) != 0x10) { printf("isic%d: Error, probe-2 failed, 0x%02x should be 0x10 for AVM A1/Fritz!\n", unit, byte); bus_space_write_1(t, h, 0, savebyte); return(ENXIO); } return(0); }