Пример #1
0
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);
}
Пример #2
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);
}
Пример #3
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;
}
Пример #4
0
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);
}
Пример #5
0
static void
fwe_identify(driver_t *driver, device_t parent)
{
	BUS_ADD_CHILD(parent, 0, "fwe", device_get_unit(parent));
}
Пример #6
0
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);
}
Пример #7
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);
}
Пример #8
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;
}
Пример #9
0
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,
					      &regs_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,
					      &regs_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);
}
Пример #10
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);
}
Пример #11
0
static int
ofwfb_scattach(device_t dev)
{
    return (sc_attach_unit(device_get_unit(dev),
                           device_get_flags(dev) | SC_AUTODETECT_KBD));
}
Пример #12
0
/*---------------------------------------------------------------------------*
 *	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);
}
Пример #13
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);
}
Пример #14
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);
}
Пример #15
0
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));
}
Пример #16
0
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);
}
Пример #17
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);
}
Пример #18
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;
}
Пример #19
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);
}
Пример #20
0
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);
}
Пример #21
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);
}
Пример #22
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);
}
Пример #23
0
/*
 * 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);
}
Пример #24
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);
}
Пример #25
0
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;
}
Пример #26
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);
}
Пример #27
0
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);
}
Пример #28
0
/*
 * 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;
}
Пример #29
0
/*
 * 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);
}
Пример #30
0
/*---------------------------------------------------------------------------*
 *	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);
}