int
do_ioremap(dev_info_t *devi, drm_device_iomap_t *iomap)
{
	int regnum;
	off_t offset;
	int ret;

	regnum =  drm_get_pci_index_reg(devi, iomap->physical,
	    iomap->size, &offset);
	if (regnum < 0) {
		DRM_ERROR("do_ioremap: can not find regster entry,"
		    " start=0x%x, size=0x%x", iomap->physical, iomap->size);
		return (ENXIO);
	}

	iomap->drm_regnum = regnum;

	ret = ddi_regs_map_setup(devi, iomap->drm_regnum,
	    (caddr_t *)&(iomap->drm_base), (offset_t)offset,
	    (offset_t)iomap->size, &dev_attr, &iomap->drm_handle);
	if (ret < 0) {
		DRM_ERROR("do_ioremap: failed to map regs: regno=%d,"
		    " offset=0x%x", regnum, offset);
		iomap->drm_handle = NULL;
		return (EFAULT);
	}

	return (0);
}
示例#2
0
/**
 * Virtio Pci attach routine, called from driver attach.
 *
 * @param pDevice           Pointer to the Virtio device instance.
 *
 * @return Solaris DDI error code. DDI_SUCCESS or DDI_FAILURE.
 */
static int VirtioPciAttach(PVIRTIODEVICE pDevice)
{
    LogFlowFunc((VIRTIOLOGNAME ":VirtioPciAttach pDevice=%p\n", pDevice));
    virtio_pci_t *pPciData = pDevice->pvHyper;
    AssertReturn(pPciData, DDI_FAILURE);

    int rc = ddi_regs_map_setup(pDevice->pDip,
                                1,                       /* reg. num */
                                &pPciData->addrIOBase,
                                0,                       /* offset */
                                0,                       /* length */
                                &g_VirtioPciAccAttrRegs,
                                &pPciData->hIO);
    if (rc == DDI_SUCCESS)
    {
        /*
         * Reset the device.
         */
        VirtioPciSetStatus(pDevice, 0);

        /*
         * Add interrupt handler.
         */
        VirtioPciSetupIRQ(pDevice->pDip);

        LogFlow((VIRTIOLOGNAME ":VirtioPciAttach: successfully mapped registers.\n"));
        return DDI_SUCCESS;
    }
    else
        LogRel((VIRTIOLOGNAME ":VirtioPciAttach: ddi_regs_map_setup failed. rc=%d\n", rc));
    return DDI_FAILURE;
}
示例#3
0
/*
 * bbc_beep_map_regs() :
 *
 *	The Keyboard Beep Control Register and Keyboard Beep Counter Register
 *	should be mapped into a non-cacheable portion of the  system
 *	addressable space.
 */
static int
bbc_beep_map_regs(dev_info_t *dip, bbc_beep_state_t *bbc_beeptr)
{
	ddi_device_acc_attr_t attr;

	BBC_BEEP_DEBUG1((CE_CONT, "bbc_beep_map_regs: Start\n"));

	/* The host controller will be little endian */
	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
	attr.devacc_attr_endian_flags  = DDI_STRUCTURE_LE_ACC;
	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;

	/* Map in operational registers */
	if (ddi_regs_map_setup(dip, 0,
	    (caddr_t *)&bbc_beeptr->bbc_beep_regsp,
	    0,
	    sizeof (bbc_beep_regs_t),
	    &attr,
	    &bbc_beeptr->bbc_beep_regs_handle) != DDI_SUCCESS) {

		return (DDI_FAILURE);
	}

	BBC_BEEP_DEBUG1((CE_CONT, "bbc_beep_map_regs: done\n"));

	return (DDI_SUCCESS);
}
示例#4
0
文件: drm_memory.c 项目: nido/pscnv
static int
__ioremap(dev_info_t *dip, drm_device_iomap_t *iomap)
{
    off_t offset;
    int regnum;
    int ret;

    regnum = drm_get_pci_index_reg(
                 dip, iomap->paddr, iomap->size, &offset);
    if (regnum < 0) {
        DRM_ERROR("can not find regster entry: "
                  "paddr=0x%x, size=0x%x", iomap->paddr, iomap->size);
        return -ENXIO;
    }

    ret = ddi_regs_map_setup(dip, regnum,
                             (caddr_t *)&(iomap->kvaddr), (offset_t)offset,
                             (offset_t)iomap->size, &dev_attr, &iomap->acc_handle);
    if (ret != DDI_SUCCESS) {
        DRM_ERROR("failed to map regs: "
                  "regnum=%d, offset=0x%x", regnum, offset);
        iomap->acc_handle = NULL;
        return -EFAULT;
    }

    return 0;
}
示例#5
0
文件: sgsbbc.c 项目: andreiw/polaris
/*
 * Map SBBC Internal registers
 *
 * The call to function should be protected by
 * chosen_lock or master_iosram->iosram_lock
 * to make sure a tunnel switch will not occur
 * in a middle of mapping.
 */
int
sbbc_map_regs(sbbc_softstate_t *softsp)
{
	struct ddi_device_acc_attr attr;

	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
	attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;

	/*
	 * Map in register set 1, Common Device Regs
	 * SBCC offset 0x0
	 */
	if (ddi_regs_map_setup(softsp->dip, RNUM_SBBC_REGS,
		(caddr_t *)&softsp->sbbc_regs,
		SBBC_REGS_OFFSET, SBBC_REGS_SIZE,
		&attr, &softsp->sbbc_reg_handle1) != DDI_SUCCESS) {

		cmn_err(CE_WARN, "sbbc%d: unable to map interrupt "
			"registers", ddi_get_instance(softsp->dip));
		return (DDI_FAILURE);
	}
	/*
	 * Map in using register set 1, EPLD
	 * SBCC offset 0xe000
	 */
	if (ddi_regs_map_setup(softsp->dip, RNUM_SBBC_REGS,
		(caddr_t *)&softsp->epld_regs,
		SBBC_EPLD_OFFSET, SBBC_EPLD_SIZE,
		&attr, &softsp->sbbc_reg_handle2) != DDI_SUCCESS) {

		cmn_err(CE_WARN, "sbbc%d: unable to map EPLD "
			"registers", ddi_get_instance(softsp->dip));
		return (DDI_FAILURE);
	}

	/*
	 * Set up pointers for registers
	 */
	softsp->port_int_regs =  (uint32_t *)((char *)softsp->sbbc_regs +
		SBBC_PCI_INT_STATUS);

map_regs_exit:
	return (DDI_SUCCESS);
}
示例#6
0
int
pci_config_setup(dev_info_t *dip, ddi_acc_handle_t *handle)
{
	caddr_t	cfgaddr;
	ddi_device_acc_attr_t attr;

	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
	attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;

	/* Check for fault management capabilities */
	if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(dip))) {
		attr.devacc_attr_version = DDI_DEVICE_ATTR_V1;
		attr.devacc_attr_access = DDI_FLAGERR_ACC;
	}

	return (ddi_regs_map_setup(dip, 0, &cfgaddr, 0, 0, &attr, handle));
}
示例#7
0
/*
 * audioixp_map_regs()
 *
 * Description:
 *	The registers are mapped in.
 *
 * Arguments:
 *	audioixp_state_t	*state		  The device's state structure
 *
 * Returns:
 *	DDI_SUCCESS		Registers successfully mapped
 *	DDI_FAILURE		Registers not successfully mapped
 */
static int
audioixp_map_regs(audioixp_state_t *statep)
{
	dev_info_t		*dip = statep->dip;

	/* map PCI config space */
	if (pci_config_setup(statep->dip, &statep->pcih) == DDI_FAILURE) {
		audio_dev_warn(statep->adev, "unable to map PCI config space");
		return (DDI_FAILURE);
	}

	/* map audio mixer register */
	if ((ddi_regs_map_setup(dip, IXP_IO_AM_REGS, &statep->regsp, 0, 0,
	    &dev_attr, &statep->regsh)) != DDI_SUCCESS) {
		audio_dev_warn(statep->adev, "unable to map audio registers");
		return (DDI_FAILURE);
	}
	return (DDI_SUCCESS);
}
示例#8
0
static int
rmc_comm_online(struct rmc_comm_state *rcs, dev_info_t *dip)
{
	ddi_acc_handle_t h;
	caddr_t p;
	int nregs;
	int err;

	if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS)
		nregs = 0;
	switch (nregs) {
	default:
	case 1:
		/*
		 *  regset 0 represents the SIO operating registers
		 */
		err = ddi_regs_map_setup(dip, 0, &p, 0, 0,
		    rmc_comm_dev_acc_attr, &h);
		if (err != DDI_SUCCESS)
			return (EIO);
		rcs->sd_state.sio_handle = h;
		rcs->sd_state.sio_regs = (void *)p;
		break;
	case 0:
		/*
		 *  If no registers are defined, succeed vacuously;
		 *  commands will be accepted, but we fake the accesses.
		 */
		break;
	}

	/*
	 * Now that the registers are mapped, we can initialise the SIO h/w
	 */
	rmc_comm_hw_reset(rcs);
	return (0);
}
示例#9
0
/*
 * audio1575_map_regs()
 *
 * Description:
 *	The registers are mapped in.
 *
 * Arguments:
 *	dev_info_t	*dip	Pointer to the device's devinfo
 *
 * Returns:
 *	DDI_SUCCESS		Registers successfully mapped
 *	DDI_FAILURE		Registers not successfully mapped
 */
static int
audio1575_map_regs(audio1575_state_t *statep)
{
	dev_info_t		*dip = statep->dip;

	/* map the M1575 Audio PCI Cfg Space */
	if (pci_config_setup(dip, &statep->pcih) != DDI_SUCCESS) {
		audio_dev_warn(statep->adev, "PCI config map failure");
		goto error;
	}

	/* map the M1575 Audio registers in PCI IO Space */
	if ((ddi_regs_map_setup(dip, M1575_AUDIO_IO_SPACE, &statep->regsp,
	    0, 0, &dev_attr, &statep->regsh)) != DDI_SUCCESS) {
		audio_dev_warn(statep->adev, "Audio IO mapping failure");
		goto error;
	}
	return (DDI_SUCCESS);

error:
	audio1575_unmap_regs(statep);

	return (DDI_FAILURE);
}
示例#10
0
/*ARGSUSED*/
static void
fipe_ioat_alloc(void *arg)
{
	int rc = 0, nregs;
	dev_info_t *dip;
	ddi_device_acc_attr_t attr;
	boolean_t fatal = B_FALSE;

	mutex_enter(&fipe_ioat_ctrl.ioat_lock);
	/*
	 * fipe_ioat_alloc() is called in DEVICE ATTACH context when loaded.
	 * In DEVICE ATTACH context, it can't call ddi_walk_devs(), so just
	 * schedule a timer and exit.
	 */
	if (fipe_ioat_ctrl.ioat_try_alloc == B_FALSE) {
		fipe_ioat_ctrl.ioat_try_alloc = B_TRUE;
		goto out_error;
	}

	/* Check whether has been initialized or encountered permanent error. */
	if (fipe_ioat_ctrl.ioat_ready || fipe_ioat_ctrl.ioat_failed ||
	    fipe_ioat_ctrl.ioat_cancel) {
		fipe_ioat_ctrl.ioat_timerid = 0;
		mutex_exit(&fipe_ioat_ctrl.ioat_lock);
		return;
	}

	if (fipe_ioat_ctrl.ioat_dev_info == NULL) {
		/* Find dev_info_t for IOAT engine. */
		ddi_walk_devs(ddi_root_node(), fipe_search_ioat_dev, NULL);
		if (fipe_ioat_ctrl.ioat_dev_info == NULL) {
			cmn_err(CE_NOTE,
			    "!fipe: no IOAT hardware found, disable pm.");
			fatal = B_TRUE;
			goto out_error;
		}
	}

	/* Map in IOAT control register window. */
	ASSERT(fipe_ioat_ctrl.ioat_dev_info != NULL);
	ASSERT(fipe_ioat_ctrl.ioat_reg_mapped == B_FALSE);
	dip = fipe_ioat_ctrl.ioat_dev_info;
	if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS || nregs < 2) {
		cmn_err(CE_WARN, "!fipe: ioat has not enough register bars.");
		fatal = B_TRUE;
		goto out_error;
	}
	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
	attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
	rc = ddi_regs_map_setup(dip, 1,
	    (caddr_t *)&fipe_ioat_ctrl.ioat_reg_addr,
	    0, 0, &attr, &fipe_ioat_ctrl.ioat_reg_handle);
	if (rc != DDI_SUCCESS) {
		cmn_err(CE_WARN, "!fipe: failed to map IOAT registeres.");
		fatal = B_TRUE;
		goto out_error;
	}

	/* Mark IOAT status. */
	fipe_ioat_ctrl.ioat_reg_mapped = B_TRUE;
	fipe_ioat_ctrl.ioat_ready = B_TRUE;
	fipe_ioat_ctrl.ioat_failed = B_FALSE;
	fipe_ioat_ctrl.ioat_timerid = 0;
	mutex_exit(&fipe_ioat_ctrl.ioat_lock);

	return;

out_error:
	fipe_ioat_ctrl.ioat_timerid = 0;
	if (!fipe_ioat_ctrl.ioat_ready && !fipe_ioat_ctrl.ioat_cancel) {
		if (fatal) {
			/* Mark permanent error and give up. */
			fipe_ioat_ctrl.ioat_failed = B_TRUE;
			/* Release reference count hold by ddi_find_devinfo. */
			if (fipe_ioat_ctrl.ioat_dev_info != NULL) {
				ndi_rele_devi(fipe_ioat_ctrl.ioat_dev_info);
				fipe_ioat_ctrl.ioat_dev_info = NULL;
			}
		} else {
			/*
			 * Schedule another timer to keep on trying.
			 * timeout() should always succeed, no need to check
			 * return.
			 */
			fipe_ioat_ctrl.ioat_timerid = timeout(fipe_ioat_alloc,
			    NULL, drv_usectohz(FIPE_IOAT_RETRY_INTERVAL));
		}
	}
	mutex_exit(&fipe_ioat_ctrl.ioat_lock);
}
示例#11
0
static int
oce_map_regs(struct oce_dev *dev)
{
	int ret = 0;
	off_t bar_size = 0;

	ASSERT(NULL != dev);
	ASSERT(NULL != dev->dip);

	/* get number of supported bars */
	ret = ddi_dev_nregs(dev->dip, &dev->num_bars);
	if (ret != DDI_SUCCESS) {
		oce_log(dev, CE_WARN, MOD_CONFIG,
		    "%d: could not retrieve num_bars", MOD_CONFIG);
		return (DDI_FAILURE);
	}

	/* verify each bar and map it accordingly */
	/* PCI CFG */
	ret = ddi_dev_regsize(dev->dip, OCE_DEV_CFG_BAR, &bar_size);
	if (ret != DDI_SUCCESS) {
		oce_log(dev, CE_WARN, MOD_CONFIG,
		    "Could not get sizeof BAR %d",
		    OCE_DEV_CFG_BAR);
		return (DDI_FAILURE);
	}

	ret = ddi_regs_map_setup(dev->dip, OCE_DEV_CFG_BAR, &dev->dev_cfg_addr,
	    0, bar_size, &reg_accattr, &dev->dev_cfg_handle);

	if (ret != DDI_SUCCESS) {
		oce_log(dev, CE_WARN, MOD_CONFIG,
		    "Could not map bar %d",
		    OCE_DEV_CFG_BAR);
		return (DDI_FAILURE);
	}

	/* CSR */
	ret = ddi_dev_regsize(dev->dip, OCE_PCI_CSR_BAR, &bar_size);

	if (ret != DDI_SUCCESS) {
		oce_log(dev, CE_WARN, MOD_CONFIG,
		    "Could not get sizeof BAR %d",
		    OCE_PCI_CSR_BAR);
		return (DDI_FAILURE);
	}

	ret = ddi_regs_map_setup(dev->dip, OCE_PCI_CSR_BAR, &dev->csr_addr,
	    0, bar_size, &reg_accattr, &dev->csr_handle);
	if (ret != DDI_SUCCESS) {
		oce_log(dev, CE_WARN, MOD_CONFIG,
		    "Could not map bar %d",
		    OCE_PCI_CSR_BAR);
		ddi_regs_map_free(&dev->dev_cfg_handle);
		return (DDI_FAILURE);
	}

	/* Doorbells */
	ret = ddi_dev_regsize(dev->dip, OCE_PCI_DB_BAR, &bar_size);
	if (ret != DDI_SUCCESS) {
		oce_log(dev, CE_WARN, MOD_CONFIG,
		    "%d Could not get sizeof BAR %d",
		    ret, OCE_PCI_DB_BAR);
		ddi_regs_map_free(&dev->csr_handle);
		ddi_regs_map_free(&dev->dev_cfg_handle);
		return (DDI_FAILURE);
	}

	ret = ddi_regs_map_setup(dev->dip, OCE_PCI_DB_BAR, &dev->db_addr,
	    0, 0, &reg_accattr, &dev->db_handle);
	if (ret != DDI_SUCCESS) {
		oce_log(dev, CE_WARN, MOD_CONFIG,
		    "Could not map bar %d", OCE_PCI_DB_BAR);
		ddi_regs_map_free(&dev->csr_handle);
		ddi_regs_map_free(&dev->dev_cfg_handle);
		return (DDI_FAILURE);
	}
	return (DDI_SUCCESS);
}
示例#12
0
static int
acebus_config(ebus_devstate_t *ebus_p)
{
	ddi_acc_handle_t conf_handle;
	uint16_t comm;
#ifdef	ACEBUS_HOTPLUG
	int tcr_reg;
	caddr_t csr_io;
	ddi_device_acc_attr_t csr_attr = {   /* CSR map attributes */
		DDI_DEVICE_ATTR_V0,
		DDI_STRUCTURE_LE_ACC,
		DDI_STRICTORDER_ACC
	};
	ddi_acc_handle_t csr_handle;
#endif

	/*
	 * Make sure the master enable and memory access enable
	 * bits are set in the config command register.
	 */
	if (pci_config_setup(ebus_p->dip, &conf_handle) != DDI_SUCCESS)
		return (0);

	comm = pci_config_get16(conf_handle, PCI_CONF_COMM),
#ifdef DEBUG
	    DBG1(D_ATTACH, ebus_p, "command register was 0x%x\n", comm);
#endif
	comm |= (PCI_COMM_ME|PCI_COMM_MAE|PCI_COMM_SERR_ENABLE|
	    PCI_COMM_PARITY_DETECT);
	pci_config_put16(conf_handle, PCI_CONF_COMM, comm),
#ifdef DEBUG
	    DBG1(D_MAP, ebus_p, "command register is now 0x%x\n",
	    pci_config_get16(conf_handle, PCI_CONF_COMM));
#endif
	pci_config_put8(conf_handle, PCI_CONF_CACHE_LINESZ,
	    (uchar_t)acebus_cache_line_size);
	pci_config_put8(conf_handle, PCI_CONF_LATENCY_TIMER,
	    (uchar_t)acebus_latency_timer);
	pci_config_teardown(&conf_handle);

#ifdef	ACEBUS_HOTPLUG
	if (acebus_update_props(ebus_p) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not update special properties.",
		    ddi_driver_name(ebus_p->dip),
		    ddi_get_instance(ebus_p->dip));
		return (0);
	}

	if (ddi_regs_map_setup(ebus_p->dip, CSR_IO_RINDEX,
	    (caddr_t *)&csr_io, 0, CSR_SIZE, &csr_attr,
	    &csr_handle) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not map Ebus CSR.",
		    ddi_driver_name(ebus_p->dip),
		    ddi_get_instance(ebus_p->dip));
	}
#ifdef	DEBUG
	if (acebus_debug_flags) {
		DBG3(D_ATTACH, ebus_p, "tcr[123] = %x,%x,%x\n",
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR1_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR2_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR3_OFF)));
		DBG2(D_ATTACH, ebus_p, "pmd-aux=%x, freq-aux=%x\n",
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    PMD_AUX_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    FREQ_AUX_OFF)));
#ifdef ACEBUS_DEBUG
		for (comm = 0; comm < 4; comm++)
			prom_printf("dcsr%d=%x, dacr%d=%x, dbcr%d=%x\n", comm,
			    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
			    0x700000+(0x2000*comm))), comm,
			    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
			    0x700000+(0x2000*comm)+4)), comm,
			    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
			    0x700000+(0x2000*comm)+8)));
#endif
	} /* acebus_debug_flags */
#endif
	/* If TCR registers are not initialized, initialize them here */
	tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
	    TCR1_OFF));
	if ((tcr_reg == 0) || (tcr_reg == -1))
		ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR1_OFF),
		    TCR1_REGVAL);
	tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
	    TCR2_OFF));
	if ((tcr_reg == 0) || (tcr_reg == -1))
		ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR2_OFF),
		    TCR2_REGVAL);
	tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
	    TCR3_OFF));
	if ((tcr_reg == 0) || (tcr_reg == -1))
		ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR3_OFF),
		    TCR3_REGVAL);
#ifdef	DEBUG
	if (acebus_debug_flags) {
		DBG3(D_ATTACH, ebus_p, "wrote tcr[123] = %x,%x,%x\n",
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR1_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR2_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR3_OFF)));
	}
#endif

	ddi_regs_map_free(&csr_handle);
#endif	/* ACEBUS_HOTPLUG */
	return (1);	/* return success */
}
示例#13
0
int
pcn_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	pcn_t			*pcnp;
	mac_register_t		*macp;
	const pcn_type_t	*pcn_type;
	int			instance = ddi_get_instance(dip);
	int			rc;
	ddi_acc_handle_t	pci;
	uint16_t		venid;
	uint16_t		devid;
	uint16_t		svid;
	uint16_t		ssid;

	switch (cmd) {
	case DDI_RESUME:
		return (pcn_ddi_resume(dip));

	case DDI_ATTACH:
		break;

	default:
		return (DDI_FAILURE);
	}

	if (ddi_slaveonly(dip) == DDI_SUCCESS) {
		pcn_error(dip, "slot does not support PCI bus-master");
		return (DDI_FAILURE);
	}

	if (ddi_intr_hilevel(dip, 0) != 0) {
		pcn_error(dip, "hilevel interrupts not supported");
		return (DDI_FAILURE);
	}

	if (pci_config_setup(dip, &pci) != DDI_SUCCESS) {
		pcn_error(dip, "unable to setup PCI config handle");
		return (DDI_FAILURE);
	}

	venid = pci_config_get16(pci, PCI_CONF_VENID);
	devid = pci_config_get16(pci, PCI_CONF_DEVID);
	svid = pci_config_get16(pci, PCI_CONF_SUBVENID);
	ssid = pci_config_get16(pci, PCI_CONF_SUBSYSID);

	if ((pcn_type = pcn_match(venid, devid)) == NULL) {
		pci_config_teardown(&pci);
		pcn_error(dip, "Unable to identify PCI card");
		return (DDI_FAILURE);
	}

	if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
	    pcn_type->pcn_name) != DDI_PROP_SUCCESS) {
		pci_config_teardown(&pci);
		pcn_error(dip, "Unable to create model property");
		return (DDI_FAILURE);
	}

	if (ddi_soft_state_zalloc(pcn_ssp, instance) != DDI_SUCCESS) {
		pcn_error(dip, "Unable to allocate soft state");
		pci_config_teardown(&pci);
		return (DDI_FAILURE);
	}

	pcnp = ddi_get_soft_state(pcn_ssp, instance);
	pcnp->pcn_dip = dip;
	pcnp->pcn_instance = instance;
	pcnp->pcn_extphyaddr = -1;

	if (ddi_get_iblock_cookie(dip, 0, &pcnp->pcn_icookie) != DDI_SUCCESS) {
		pcn_error(pcnp->pcn_dip, "ddi_get_iblock_cookie failed");
		ddi_soft_state_free(pcn_ssp, instance);
		pci_config_teardown(&pci);
		return (DDI_FAILURE);
	}


	mutex_init(&pcnp->pcn_xmtlock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie);
	mutex_init(&pcnp->pcn_intrlock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie);
	mutex_init(&pcnp->pcn_reglock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie);

	/*
	 * Enable bus master, IO space, and memory space accesses
	 */
	pci_config_put16(pci, PCI_CONF_COMM,
	    pci_config_get16(pci, PCI_CONF_COMM) | PCI_COMM_ME | PCI_COMM_MAE);

	pci_config_teardown(&pci);

	if (ddi_regs_map_setup(dip, 1, (caddr_t *)&pcnp->pcn_regs, 0, 0,
	    &pcn_devattr, &pcnp->pcn_regshandle)) {
		pcn_error(dip, "ddi_regs_map_setup failed");
		goto fail;
	}

	if (pcn_set_chipid(pcnp, (uint32_t)ssid << 16 | (uint32_t)svid) !=
	    DDI_SUCCESS) {
		goto fail;
	}

	if ((pcnp->pcn_mii = mii_alloc(pcnp, dip, &pcn_mii_ops)) == NULL)
		goto fail;

	/* XXX: need to set based on device */
	mii_set_pauseable(pcnp->pcn_mii, B_FALSE, B_FALSE);

	if ((pcn_allocrxring(pcnp) != DDI_SUCCESS) ||
	    (pcn_alloctxring(pcnp) != DDI_SUCCESS)) {
		pcn_error(dip, "unable to allocate DMA resources");
		goto fail;
	}

	pcnp->pcn_promisc = B_FALSE;

	mutex_enter(&pcnp->pcn_intrlock);
	mutex_enter(&pcnp->pcn_xmtlock);
	rc = pcn_initialize(pcnp, B_TRUE);
	mutex_exit(&pcnp->pcn_xmtlock);
	mutex_exit(&pcnp->pcn_intrlock);
	if (rc != DDI_SUCCESS)
		goto fail;

	if (ddi_add_intr(dip, 0, NULL, NULL, pcn_intr, (caddr_t)pcnp) !=
	    DDI_SUCCESS) {
		pcn_error(dip, "unable to add interrupt");
		goto fail;
	}

	pcnp->pcn_flags |= PCN_INTR_ENABLED;

	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
		pcn_error(pcnp->pcn_dip, "mac_alloc failed");
		goto fail;
	}

	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
	macp->m_driver = pcnp;
	macp->m_dip = dip;
	macp->m_src_addr = pcnp->pcn_addr;
	macp->m_callbacks = &pcn_m_callbacks;
	macp->m_min_sdu = 0;
	macp->m_max_sdu = ETHERMTU;
	macp->m_margin = VLAN_TAGSZ;

	if (mac_register(macp, &pcnp->pcn_mh) == DDI_SUCCESS) {
		mac_free(macp);
		return (DDI_SUCCESS);
	}

	mac_free(macp);

	return (DDI_SUCCESS);

fail:
	pcn_teardown(pcnp);
	return (DDI_FAILURE);
}
示例#14
0
文件: kb8042.c 项目: andreiw/polaris
static int
kb8042_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	int	rc;
	int	scanset;
	int	leds;

	struct kb8042	*kb8042 = &Kdws;
	static ddi_device_acc_attr_t attr = {
		DDI_DEVICE_ATTR_V0,
		DDI_NEVERSWAP_ACC,
		DDI_STRICTORDER_ACC,
	};

	switch (cmd) {
	case DDI_RESUME:
		leds = kb8042->leds.commanded;
		kb8042->w_init = 0;
		kb8042_init(kb8042, B_TRUE);
		kb8042_setled(kb8042, leds, B_FALSE);
		return (DDI_SUCCESS);

	case DDI_ATTACH:
		if (kb8042_dip != NULL)
			return (DDI_FAILURE);
		/* The rest of the function is for attach */
		break;

	default:
		return (DDI_FAILURE);
	}

	kb8042->debugger.mod1 = 58;	/* Left Ctrl */
	kb8042->debugger.mod2 = 60;	/* Left Alt */
	kb8042->debugger.trigger = 33;	/* D */
	kb8042->debugger.mod1_down = B_FALSE;
	kb8042->debugger.mod2_down = B_FALSE;
	kb8042->debugger.enabled = B_FALSE;

	kb8042_dip = devi;
	kb8042->init_state = KB8042_UNINITIALIZED;

	kb8042->polled_synthetic_release_pending = B_FALSE;

	if (ddi_create_minor_node(devi, module_name, S_IFCHR, 0,
		    DDI_NT_KEYBOARD, 0) == DDI_FAILURE) {
		goto failure;
	}

	kb8042->init_state |= KB8042_MINOR_NODE_CREATED;

	rc = ddi_regs_map_setup(devi, 0, (caddr_t *)&kb8042->addr,
		(offset_t)0, (offset_t)0, &attr, &kb8042->handle);
	if (rc != DDI_SUCCESS) {
#if	defined(KD_DEBUG)
		cmn_err(CE_WARN, "kb8042_attach:  can't map registers");
#endif
		goto failure;
	}

	kb8042->init_state |= KB8042_REGS_MAPPED;

	if (ddi_get_iblock_cookie(devi, 0, &kb8042->w_iblock) !=
		DDI_SUCCESS) {
		cmn_err(CE_WARN, "kb8042_attach:  Can't get iblock cookie");
		goto failure;
	}

	mutex_init(&kb8042->w_hw_mutex, NULL, MUTEX_DRIVER, kb8042->w_iblock);

	kb8042->init_state |= KB8042_HW_MUTEX_INITTED;

	kb8042_init(kb8042, B_FALSE);

#ifdef __sparc
	/* Detect the scan code set currently in use */
	scanset = kb8042_read_scanset(kb8042, B_TRUE);

	if (scanset < 0 && kb8042_warn_unknown_scanset) {

		cmn_err(CE_WARN, "Cannot determine keyboard scan code set ");
		cmn_err(CE_CONT, "(is the keyboard plugged in?). ");
		cmn_err(CE_CONT, "Defaulting to scan code set %d.  If the "
		    "keyboard does not ", kb8042_default_scanset);
		cmn_err(CE_CONT, "work properly, add "
		    "`set kb8042:kb8042_default_scanset=%d' to /etc/system ",
		    (kb8042_default_scanset == 1) ? 2 : 1);
		cmn_err(CE_CONT, "(via network or with a USB keyboard) and "
		    "restart the system.  If you ");
		cmn_err(CE_CONT, "do not want to see this message in the "
		    "future, add ");
		cmn_err(CE_CONT, "`set kb8042:kb8042_warn_unknown_scanset=0' "
		    "to /etc/system.\n");

		/* Use the default scan code set. */
		scanset = kb8042_default_scanset;
	}
#else
	/* x86 systems use scan code set 1 -- no detection required */
	scanset = 1;
#endif
	if (KeyboardConvertScan_init(kb8042, scanset) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "Cannot initialize keyboard scan converter: "
		    "Unknown scan code set `%d'.", scanset);
		/* Scan code set is not supported */
		goto failure;
	}

	/*
	 * Turn on interrupts...
	 */
	if (ddi_add_intr(devi, 0,
		&kb8042->w_iblock, (ddi_idevice_cookie_t *)NULL,
		kb8042_intr, (caddr_t)kb8042) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "kb8042_attach: cannot add interrupt");
		goto failure;
	}

	kb8042->init_state |= KB8042_INTR_ADDED;

	ddi_report_dev(devi);

#ifdef	KD_DEBUG
	cmn_err(CE_CONT, "?%s #%d: version %s\n",
	    DRIVER_NAME(devi), ddi_get_instance(devi), "1.66 (06/04/07)");
#endif

	return (DDI_SUCCESS);

failure:
	kb8042_cleanup(kb8042);
	return (DDI_FAILURE);
}
示例#15
0
static int
mouse8042_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	struct mouse_state *state;
	mblk_t *mp;
	int instance = ddi_get_instance(dip);
	static ddi_device_acc_attr_t attr = {
		DDI_DEVICE_ATTR_V0,
		DDI_NEVERSWAP_ACC,
		DDI_STRICTORDER_ACC,
	};
	int rc;


	if (cmd == DDI_RESUME) {
		state = (struct mouse_state *)ddi_get_driver_private(dip);

		/* Ready to handle inbound data from mouse8042_intr */
		state->ready = 1;

		/*
		 * Send a 0xaa 0x00 upstream.
		 * This causes the vuid module to reset the mouse.
		 */
		if (state->ms_rqp != NULL) {
			if (mp = allocb(1, BPRI_MED)) {
				*mp->b_wptr++ = 0xaa;
				putnext(state->ms_rqp, mp);
			}
			if (mp = allocb(1, BPRI_MED)) {
				*mp->b_wptr++ = 0x0;
				putnext(state->ms_rqp, mp);
			}
		}
		return (DDI_SUCCESS);
	}

	if (cmd != DDI_ATTACH)
		return (DDI_FAILURE);

	if (mouse8042_dip != NULL)
		return (DDI_FAILURE);

	/* allocate and initialize state structure */
	state = kmem_zalloc(sizeof (struct mouse_state), KM_SLEEP);
	state->ms_opened = B_FALSE;
	state->reset_state = MSE_RESET_IDLE;
	state->reset_tid = 0;
	state->bc_id = 0;
	ddi_set_driver_private(dip, state);

	/*
	 * In order to support virtual keyboard/mouse, we should distinguish
	 * between internal virtual open and external physical open.
	 *
	 * When the physical devices are opened by application, they will
	 * be unlinked from the virtual device and their data stream will
	 * not be sent to the virtual device. When the opened physical
	 * devices are closed, they will be relinked to the virtual devices.
	 *
	 * All these automatic switch between virtual and physical are
	 * transparent.
	 *
	 * So we change minor node numbering scheme to be:
	 * 	external node minor num == instance * 2
	 *	internal node minor num == instance * 2 + 1
	 */
	rc = ddi_create_minor_node(dip, "mouse", S_IFCHR, instance * 2,
	    DDI_NT_MOUSE, NULL);
	if (rc != DDI_SUCCESS) {
		goto fail_1;
	}

	if (ddi_create_internal_pathname(dip, "internal_mouse", S_IFCHR,
	    instance * 2 + 1) != DDI_SUCCESS) {
		goto fail_2;
	}

	rc = ddi_regs_map_setup(dip, 0, (caddr_t *)&state->ms_addr,
	    (offset_t)0, (offset_t)0, &attr, &state->ms_handle);
	if (rc != DDI_SUCCESS) {
		goto fail_2;
	}

	rc = ddi_get_iblock_cookie(dip, 0, &state->ms_iblock_cookie);
	if (rc != DDI_SUCCESS) {
		goto fail_3;
	}

	mutex_init(&state->ms_mutex, NULL, MUTEX_DRIVER,
	    state->ms_iblock_cookie);
	mutex_init(&state->reset_mutex, NULL, MUTEX_DRIVER,
	    state->ms_iblock_cookie);
	cv_init(&state->reset_cv, NULL, CV_DRIVER, NULL);

	rc = ddi_add_intr(dip, 0,
	    (ddi_iblock_cookie_t *)NULL, (ddi_idevice_cookie_t *)NULL,
	    mouse8042_intr, (caddr_t)state);
	if (rc != DDI_SUCCESS) {
		goto fail_3;
	}

	mouse8042_dip = dip;

	/* Ready to handle inbound data from mouse8042_intr */
	state->ready = 1;

	/* Now that we're attached, announce our presence to the world. */
	ddi_report_dev(dip);
	return (DDI_SUCCESS);

fail_3:
	ddi_regs_map_free(&state->ms_handle);

fail_2:
	ddi_remove_minor_node(dip, NULL);

fail_1:
	kmem_free(state, sizeof (struct mouse_state));
	return (rc);
}
示例#16
0
void
pci_dump(void *arg)
{
	igb_t *igb = (igb_t *)arg;
	ddi_acc_handle_t handle;
	uint8_t cap_ptr;
	uint8_t next_ptr;
	uint32_t msix_bar;
	uint32_t msix_ctrl;
	uint32_t msix_tbl_sz;
	uint32_t tbl_offset;
	uint32_t tbl_bir;
	uint32_t pba_offset;
	uint32_t pba_bir;
	off_t offset;
	off_t mem_size;
	uintptr_t base;
	ddi_acc_handle_t acc_hdl;
	int i;

	handle = igb->osdep.cfg_handle;

	igb_log(igb, "Begin dump PCI config space");

	igb_log(igb,
	    "PCI_CONF_VENID:\t0x%x\n",
	    pci_config_get16(handle, PCI_CONF_VENID));
	igb_log(igb,
	    "PCI_CONF_DEVID:\t0x%x\n",
	    pci_config_get16(handle, PCI_CONF_DEVID));
	igb_log(igb,
	    "PCI_CONF_COMMAND:\t0x%x\n",
	    pci_config_get16(handle, PCI_CONF_COMM));
	igb_log(igb,
	    "PCI_CONF_STATUS:\t0x%x\n",
	    pci_config_get16(handle, PCI_CONF_STAT));
	igb_log(igb,
	    "PCI_CONF_REVID:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_REVID));
	igb_log(igb,
	    "PCI_CONF_PROG_CLASS:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_PROGCLASS));
	igb_log(igb,
	    "PCI_CONF_SUB_CLASS:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_SUBCLASS));
	igb_log(igb,
	    "PCI_CONF_BAS_CLASS:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_BASCLASS));
	igb_log(igb,
	    "PCI_CONF_CACHE_LINESZ:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_CACHE_LINESZ));
	igb_log(igb,
	    "PCI_CONF_LATENCY_TIMER:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_LATENCY_TIMER));
	igb_log(igb,
	    "PCI_CONF_HEADER_TYPE:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_HEADER));
	igb_log(igb,
	    "PCI_CONF_BIST:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_BIST));
	igb_log(igb,
	    "PCI_CONF_BASE0:\t0x%x\n",
	    pci_config_get32(handle, PCI_CONF_BASE0));
	igb_log(igb,
	    "PCI_CONF_BASE1:\t0x%x\n",
	    pci_config_get32(handle, PCI_CONF_BASE1));
	igb_log(igb,
	    "PCI_CONF_BASE2:\t0x%x\n",
	    pci_config_get32(handle, PCI_CONF_BASE2));

	/* MSI-X BAR */
	msix_bar = pci_config_get32(handle, PCI_CONF_BASE3);
	igb_log(igb,
	    "PCI_CONF_BASE3:\t0x%x\n", msix_bar);

	igb_log(igb,
	    "PCI_CONF_BASE4:\t0x%x\n",
	    pci_config_get32(handle, PCI_CONF_BASE4));
	igb_log(igb,
	    "PCI_CONF_BASE5:\t0x%x\n",
	    pci_config_get32(handle, PCI_CONF_BASE5));
	igb_log(igb,
	    "PCI_CONF_CIS:\t0x%x\n",
	    pci_config_get32(handle, PCI_CONF_CIS));
	igb_log(igb,
	    "PCI_CONF_SUBVENID:\t0x%x\n",
	    pci_config_get16(handle, PCI_CONF_SUBVENID));
	igb_log(igb,
	    "PCI_CONF_SUBSYSID:\t0x%x\n",
	    pci_config_get16(handle, PCI_CONF_SUBSYSID));
	igb_log(igb,
	    "PCI_CONF_ROM:\t0x%x\n",
	    pci_config_get32(handle, PCI_CONF_ROM));

	cap_ptr = pci_config_get8(handle, PCI_CONF_CAP_PTR);

	igb_log(igb,
	    "PCI_CONF_CAP_PTR:\t0x%x\n", cap_ptr);
	igb_log(igb,
	    "PCI_CONF_ILINE:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_ILINE));
	igb_log(igb,
	    "PCI_CONF_IPIN:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_IPIN));
	igb_log(igb,
	    "PCI_CONF_MIN_G:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_MIN_G));
	igb_log(igb,
	    "PCI_CONF_MAX_L:\t0x%x\n",
	    pci_config_get8(handle, PCI_CONF_MAX_L));

	/* Power Management */
	offset = cap_ptr;

	igb_log(igb,
	    "PCI_PM_CAP_ID:\t0x%x\n",
	    pci_config_get8(handle, offset));

	next_ptr = pci_config_get8(handle, offset + 1);

	igb_log(igb,
	    "PCI_PM_NEXT_PTR:\t0x%x\n", next_ptr);
	igb_log(igb,
	    "PCI_PM_CAP:\t0x%x\n",
	    pci_config_get16(handle, offset + PCI_PMCAP));
	igb_log(igb,
	    "PCI_PM_CSR:\t0x%x\n",
	    pci_config_get16(handle, offset + PCI_PMCSR));
	igb_log(igb,
	    "PCI_PM_CSR_BSE:\t0x%x\n",
	    pci_config_get8(handle, offset + PCI_PMCSR_BSE));
	igb_log(igb,
	    "PCI_PM_DATA:\t0x%x\n",
	    pci_config_get8(handle, offset + PCI_PMDATA));

	/* MSI Configuration */
	offset = next_ptr;

	igb_log(igb,
	    "PCI_MSI_CAP_ID:\t0x%x\n",
	    pci_config_get8(handle, offset));

	next_ptr = pci_config_get8(handle, offset + 1);

	igb_log(igb,
	    "PCI_MSI_NEXT_PTR:\t0x%x\n", next_ptr);
	igb_log(igb,
	    "PCI_MSI_CTRL:\t0x%x\n",
	    pci_config_get16(handle, offset + PCI_MSI_CTRL));
	igb_log(igb,
	    "PCI_MSI_ADDR:\t0x%x\n",
	    pci_config_get32(handle, offset + PCI_MSI_ADDR_OFFSET));
	igb_log(igb,
	    "PCI_MSI_ADDR_HI:\t0x%x\n",
	    pci_config_get32(handle, offset + 0x8));
	igb_log(igb,
	    "PCI_MSI_DATA:\t0x%x\n",
	    pci_config_get16(handle, offset + 0xC));

	/* MSI-X Configuration */
	offset = next_ptr;

	igb_log(igb,
	    "PCI_MSIX_CAP_ID:\t0x%x\n",
	    pci_config_get8(handle, offset));

	next_ptr = pci_config_get8(handle, offset + 1);
	igb_log(igb,
	    "PCI_MSIX_NEXT_PTR:\t0x%x\n", next_ptr);

	msix_ctrl = pci_config_get16(handle, offset + PCI_MSIX_CTRL);
	msix_tbl_sz = msix_ctrl & 0x7ff;
	igb_log(igb,
	    "PCI_MSIX_CTRL:\t0x%x\n", msix_ctrl);

	tbl_offset = pci_config_get32(handle, offset + PCI_MSIX_TBL_OFFSET);
	tbl_bir = tbl_offset & PCI_MSIX_TBL_BIR_MASK;
	tbl_offset = tbl_offset & ~PCI_MSIX_TBL_BIR_MASK;
	igb_log(igb,
	    "PCI_MSIX_TBL_OFFSET:\t0x%x\n", tbl_offset);
	igb_log(igb,
	    "PCI_MSIX_TBL_BIR:\t0x%x\n", tbl_bir);

	pba_offset = pci_config_get32(handle, offset + PCI_MSIX_PBA_OFFSET);
	pba_bir = pba_offset & PCI_MSIX_PBA_BIR_MASK;
	pba_offset = pba_offset & ~PCI_MSIX_PBA_BIR_MASK;
	igb_log(igb,
	    "PCI_MSIX_PBA_OFFSET:\t0x%x\n", pba_offset);
	igb_log(igb,
	    "PCI_MSIX_PBA_BIR:\t0x%x\n", pba_bir);

	/* PCI Express Configuration */
	offset = next_ptr;

	igb_log(igb,
	    "PCIE_CAP_ID:\t0x%x\n",
	    pci_config_get8(handle, offset + PCIE_CAP_ID));

	next_ptr = pci_config_get8(handle, offset + PCIE_CAP_NEXT_PTR);

	igb_log(igb,
	    "PCIE_CAP_NEXT_PTR:\t0x%x\n", next_ptr);
	igb_log(igb,
	    "PCIE_PCIECAP:\t0x%x\n",
	    pci_config_get16(handle, offset + PCIE_PCIECAP));
	igb_log(igb,
	    "PCIE_DEVCAP:\t0x%x\n",
	    pci_config_get32(handle, offset + PCIE_DEVCAP));
	igb_log(igb,
	    "PCIE_DEVCTL:\t0x%x\n",
	    pci_config_get16(handle, offset + PCIE_DEVCTL));
	igb_log(igb,
	    "PCIE_DEVSTS:\t0x%x\n",
	    pci_config_get16(handle, offset + PCIE_DEVSTS));
	igb_log(igb,
	    "PCIE_LINKCAP:\t0x%x\n",
	    pci_config_get32(handle, offset + PCIE_LINKCAP));
	igb_log(igb,
	    "PCIE_LINKCTL:\t0x%x\n",
	    pci_config_get16(handle, offset + PCIE_LINKCTL));
	igb_log(igb,
	    "PCIE_LINKSTS:\t0x%x\n",
	    pci_config_get16(handle, offset + PCIE_LINKSTS));

	/* MSI-X Memory Space */
	if (ddi_dev_regsize(igb->dip, IGB_ADAPTER_MSIXTAB, &mem_size) !=
	    DDI_SUCCESS) {
		igb_log(igb, "ddi_dev_regsize() failed");
		return;
	}

	if ((ddi_regs_map_setup(igb->dip, IGB_ADAPTER_MSIXTAB, (caddr_t *)&base,
	    0, mem_size, &igb_regs_acc_attr, &acc_hdl)) != DDI_SUCCESS) {
		igb_log(igb, "ddi_regs_map_setup() failed");
		return;
	}

	igb_log(igb, "MSI-X Memory Space: (mem_size = %d, base = %x)",
	    mem_size, base);

	for (i = 0; i <= msix_tbl_sz; i++) {
		igb_log(igb, "MSI-X Table Entry(%d):", i);
		igb_log(igb, "lo_addr:\t%x",
		    ddi_get32(acc_hdl,
		    (uint32_t *)(base + tbl_offset + (i * 16))));
		igb_log(igb, "up_addr:\t%x",
		    ddi_get32(acc_hdl,
		    (uint32_t *)(base + tbl_offset + (i * 16) + 4)));
		igb_log(igb, "msg_data:\t%x",
		    ddi_get32(acc_hdl,
		    (uint32_t *)(base + tbl_offset + (i * 16) + 8)));
		igb_log(igb, "vct_ctrl:\t%x",
		    ddi_get32(acc_hdl,
		    (uint32_t *)(base + tbl_offset + (i * 16) + 12)));
	}

	igb_log(igb, "MSI-X Pending Bits:\t%x",
	    ddi_get32(acc_hdl, (uint32_t *)(base + pba_offset)));

	ddi_regs_map_free(&acc_hdl);
}
示例#17
0
static int
gpio_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{

	int instance;
	struct gpio_softc *softc = NULL;
	ddi_device_acc_attr_t dev_attr;

	switch (cmd) {

	case DDI_ATTACH:

	    /* Allocate and get the soft state structure for this instance. */

	    instance = ddi_get_instance(dip);
	    DBG(dip, "attach: instance is %d", instance, 0, 0, 0, 0);
	    if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
		goto attach_failed;
	    softc = getsoftc(instance);
	    softc->gp_dip = dip;
	    softc->gp_state = 0;
	    mutex_init(&softc->gp_mutex, NULL, MUTEX_DRIVER, NULL);

	    /* Map in the gpio device registers. */

	    dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
	    dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
	    dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
	    if (ddi_regs_map_setup(dip, 0, (caddr_t *)&softc->gp_regs, 0, 0,
		    &dev_attr, &softc->gp_handle) != DDI_SUCCESS)
		goto attach_failed;
	    DBG(dip, "attach: regs=0x%p", (uintptr_t)softc->gp_regs,
		0, 0, 0, 0);
	    DBG(dip, "attach: port 1 data is %x",
		(uintptr_t)ddi_get8(softc->gp_handle, &softc->gp_regs[0]),
		0, 0, 0, 0);
	    DBG(dip, "attach: port 1 direction is %x",
		(uintptr_t)ddi_get8(softc->gp_handle, &softc->gp_regs[1]),
		0, 0, 0, 0);
	    DBG(dip, "attach: port 1 output type is %x",
		(uintptr_t)ddi_get8(softc->gp_handle, &softc->gp_regs[2]),
		0, 0, 0, 0);
	    DBG(dip, "attach: port 1 pull up control type is %x",
		(uintptr_t)ddi_get8(softc->gp_handle, &softc->gp_regs[3]),
		0, 0, 0, 0);
	    DBG(dip, "attach: port 2 data is %x",
		(uintptr_t)ddi_get8(softc->gp_handle, &softc->gp_regs[4]),
		0, 0, 0, 0);
	    DBG(dip, "attach: port 2 direction is %x",
		(uintptr_t)ddi_get8(softc->gp_handle, &softc->gp_regs[5]),
		0, 0, 0, 0);
	    DBG(dip, "attach: port 2 output type is %x",
		(uintptr_t)ddi_get8(softc->gp_handle, &softc->gp_regs[6]),
		0, 0, 0, 0);
	    DBG(dip, "attach: port 2 pull up control type is %x",
		(uintptr_t)ddi_get8(softc->gp_handle, &softc->gp_regs[7]),
		0, 0, 0, 0);

	    /* Create device minor nodes. */

	    if (ddi_create_minor_node(dip, "gpio", S_IFCHR,
		instance, NULL, NULL) == DDI_FAILURE) {
		ddi_regs_map_free(&softc->gp_handle);
		goto attach_failed;
	    }

	    ddi_report_dev(dip);
	    return (DDI_SUCCESS);

	case DDI_RESUME:

	    /* Nothing to do for a resume. */

	    return (DDI_SUCCESS);

	default:
	    return (DDI_FAILURE);
	}

attach_failed:
	if (softc) {
	    mutex_destroy(&softc->gp_mutex);
	    if (softc->gp_handle)
		ddi_regs_map_free(&softc->gp_handle);
	    ddi_soft_state_free(statep, instance);
	    ddi_remove_minor_node(dip, NULL);
	}
	return (DDI_FAILURE);
}
示例#18
0
/**
 * Attach entry point, to attach a device to the system or resume it.
 *
 * @param   pDip            The module structure instance.
 * @param   enmCmd          Attach type (ddi_attach_cmd_t)
 *
 * @return  corresponding solaris error code.
 */
static int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
{
    LogFlow((DEVICE_NAME "::Attach\n"));
    switch (enmCmd)
    {
        case DDI_ATTACH:
        {
            if (g_pDip)
            {
                LogRel((DEVICE_NAME "::Attach: Only one instance supported.\n"));
                return DDI_FAILURE;
            }

            int instance = ddi_get_instance(pDip);

            /*
             * Enable resources for PCI access.
             */
            ddi_acc_handle_t PciHandle;
            int rc = pci_config_setup(pDip, &PciHandle);
            if (rc == DDI_SUCCESS)
            {
                /*
                 * Map the register address space.
                 */
                caddr_t baseAddr;
                ddi_device_acc_attr_t deviceAttr;
                deviceAttr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
                deviceAttr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
                deviceAttr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
                deviceAttr.devacc_attr_access = DDI_DEFAULT_ACC;
                rc = ddi_regs_map_setup(pDip, 1, &baseAddr, 0, 0, &deviceAttr, &g_PciIOHandle);
                if (rc == DDI_SUCCESS)
                {
                    /*
                     * Read size of the MMIO region.
                     */
                    g_uIOPortBase = (uintptr_t)baseAddr;
                    rc = ddi_dev_regsize(pDip, 2, &g_cbMMIO);
                    if (rc == DDI_SUCCESS)
                    {
                        rc = ddi_regs_map_setup(pDip, 2, &g_pMMIOBase, 0, g_cbMMIO, &deviceAttr,
                                        &g_PciMMIOHandle);
                        if (rc == DDI_SUCCESS)
                        {
                            /*
                             * Add IRQ of VMMDev.
                             */
                            rc = VBoxGuestSolarisAddIRQ(pDip);
                            if (rc == DDI_SUCCESS)
                            {
                                /*
                                 * Call the common device extension initializer.
                                 */
                                rc = VBoxGuestInitDevExt(&g_DevExt, g_uIOPortBase, g_pMMIOBase, g_cbMMIO,
#if ARCH_BITS == 64
                                                         VBOXOSTYPE_Solaris_x64,
#else
                                                         VBOXOSTYPE_Solaris,
#endif
                                                         VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
                                if (RT_SUCCESS(rc))
                                {
                                    rc = ddi_create_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0);
                                    if (rc == DDI_SUCCESS)
                                    {
                                        g_pDip = pDip;
                                        pci_config_teardown(&PciHandle);
                                        return DDI_SUCCESS;
                                    }

                                    LogRel((DEVICE_NAME "::Attach: ddi_create_minor_node failed.\n"));
                                    VBoxGuestDeleteDevExt(&g_DevExt);
                                }
                                else
                                    LogRel((DEVICE_NAME "::Attach: VBoxGuestInitDevExt failed.\n"));
                                VBoxGuestSolarisRemoveIRQ(pDip);
                            }
                            else
                                LogRel((DEVICE_NAME "::Attach: VBoxGuestSolarisAddIRQ failed.\n"));
                            ddi_regs_map_free(&g_PciMMIOHandle);
                        }
                        else
                            LogRel((DEVICE_NAME "::Attach: ddi_regs_map_setup for MMIO region failed.\n"));
                    }
                    else
                        LogRel((DEVICE_NAME "::Attach: ddi_dev_regsize for MMIO region failed.\n"));
                    ddi_regs_map_free(&g_PciIOHandle);
                }
                else
                    LogRel((DEVICE_NAME "::Attach: ddi_regs_map_setup for IOport failed.\n"));
                pci_config_teardown(&PciHandle);
            }
            else
                LogRel((DEVICE_NAME "::Attach: pci_config_setup failed rc=%d.\n", rc));
            return DDI_FAILURE;
        }

        case DDI_RESUME:
        {
            /** @todo implement resume for guest driver. */
            return DDI_SUCCESS;
        }

        default:
            return DDI_FAILURE;
    }
}
示例#19
0
static int
virtionet_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	virtionet_state_t	*sp;
	int			instance;
	int			rc;

	switch (cmd) {
	case DDI_ATTACH:
		break;
	case DDI_RESUME:
	default:
		return (DDI_FAILURE);
	}

	/* Sanity check - make sure this is indeed virtio PCI device */
	if (virtio_validate_pcidev(dip) != DDI_SUCCESS) {
		return (DDI_FAILURE);
	}

	instance = ddi_get_instance(dip);
	if (ddi_soft_state_zalloc(virtionet_statep, instance) != DDI_SUCCESS) {
		return (DDI_FAILURE);
	}

	sp = ddi_get_soft_state(virtionet_statep, instance);
	ASSERT(sp);
	sp->dip = dip;

	/* Map virtionet PCI header */
	rc = ddi_regs_map_setup(sp->dip, 1, &sp->hdraddr, 0,
	    VIRTIO_DEVICE_SPECIFIC, &virtio_devattr, &sp->hdrhandle);
	if (rc != DDI_SUCCESS) {
		ddi_soft_state_free(virtionet_statep, instance);
		return (DDI_FAILURE);
	}

	/*
	 * The device specific portion is *always* in guest native mode,
	 * so it can be accessed directly, w/o ddi_get()/ddi_put() machinery.
	 */
	/* Map virtionet device specific configuration area */
	off_t	len;
	if (ddi_dev_regsize(sp->dip, 1, &len) != DDI_SUCCESS) {
		ddi_regs_map_free(&sp->hdrhandle);
		ddi_soft_state_free(virtionet_statep, instance);
		return (DDI_FAILURE);
	}
	rc = ddi_regs_map_setup(sp->dip, 1, &sp->devaddr,
	    VIRTIO_DEVICE_SPECIFIC, len - VIRTIO_DEVICE_SPECIFIC,
	    &virtio_devattr, &sp->devhandle);
	if (rc != DDI_SUCCESS) {
		ddi_regs_map_free(&sp->hdrhandle);
		ddi_soft_state_free(virtionet_statep, instance);
		return (DDI_FAILURE);
	}

	cmn_err(CE_CONT, "PCI header %p, device specific %p\n",
	    sp->hdraddr, sp->devaddr);
/*
	sp->devcfg =
	    (virtio_net_config_t *)(sp->hdraddr + VIRTIO_DEVICE_SPECIFIC);
*/

	/* Reset device - we are going to re-negotiate feature set */
	VIRTIO_DEV_RESET(sp);

	/* Acknowledge the presense of the device */
	VIRTIO_DEV_ACK(sp);

	rc = virtio_validate_netdev(sp);
	if (rc != DDI_SUCCESS) {
		ddi_regs_map_free(&sp->devhandle);
		ddi_regs_map_free(&sp->hdrhandle);
		ddi_soft_state_free(virtionet_statep, instance);
		return (DDI_FAILURE);
	}
	/* We know how to drive this device */
	VIRTIO_DEV_DRIVER(sp);

	rc = virtionet_negotiate_features(sp);
	if (rc != DDI_SUCCESS) {
		ddi_regs_map_free(&sp->devhandle);
		ddi_regs_map_free(&sp->hdrhandle);
		ddi_soft_state_free(virtionet_statep, instance);
		return (DDI_FAILURE);
	}

	virtionet_get_macaddr(sp);

	rc = virtionet_vq_setup(sp);
	if (rc != DDI_SUCCESS) {
		ddi_regs_map_free(&sp->devhandle);
		ddi_regs_map_free(&sp->hdrhandle);
		ddi_soft_state_free(virtionet_statep, instance);
		return (DDI_FAILURE);
	}

	rc = virtionet_intr_setup(sp);
	if (rc != DDI_SUCCESS) {
		virtionet_vq_teardown(sp);
		ddi_regs_map_free(&sp->devhandle);
		ddi_regs_map_free(&sp->hdrhandle);
		ddi_soft_state_free(virtionet_statep, instance);
		return (DDI_FAILURE);
	}

	rc = virtionet_mac_register(sp);
	if (rc != DDI_SUCCESS) {
		(void) virtionet_intr_teardown(sp);
		virtionet_vq_teardown(sp);
		ddi_regs_map_free(&sp->devhandle);
		ddi_regs_map_free(&sp->hdrhandle);
		ddi_soft_state_free(virtionet_statep, instance);
		return (DDI_FAILURE);
	}

	ddi_report_dev(dip);

	return (DDI_SUCCESS);
}
int
gfxp_vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd,
	gfxp_vgatext_softc_ptr_t ptr)
{
	struct vgatext_softc *softc = (struct vgatext_softc *)ptr;
	int	unit = ddi_get_instance(devi);
	int	error;
	char	*parent_type = NULL;
	int	reg_rnumber;
	off_t	reg_offset;
	off_t	mem_offset;
	char	*cons;
	int pci_pcie_bus = 0;
	int value;

	switch (cmd) {
	case DDI_ATTACH:
		break;

	case DDI_RESUME:
		vgatext_resume(softc);
		return (DDI_SUCCESS);

	default:
		return (DDI_FAILURE);
	}

	/* DDI_ATTACH */

	softc->devi = devi; /* Copy and init DEVI */

	softc->polledio.arg = (struct vis_polledio_arg *)softc;
	softc->polledio.display = vgatext_polled_display;
	softc->polledio.copy = vgatext_polled_copy;
	softc->polledio.cursor = vgatext_polled_cursor;

	mutex_init(&(softc->lock), NULL, MUTEX_DRIVER, NULL);

	error = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(devi),
	    DDI_PROP_DONTPASS, "device_type", &parent_type);
	if (error != DDI_SUCCESS) {
		cmn_err(CE_WARN, MYNAME ": can't determine parent type.");
		goto fail;
	}

	/* Not enable AGP and DRM by default */
	if (STREQ(parent_type, "isa") || STREQ(parent_type, "eisa")) {
		reg_rnumber = vgatext_get_isa_reg_index(devi, 1, VGA_REG_ADDR,
		    &reg_offset);
		if (reg_rnumber < 0) {
			cmn_err(CE_WARN,
			    MYNAME
			    ": can't find reg entry for registers");
			error = DDI_FAILURE;
			goto fail;
		}
		softc->fb_regno = vgatext_get_isa_reg_index(devi, 0,
		    VGA_MEM_ADDR, &mem_offset);
		if (softc->fb_regno < 0) {
			cmn_err(CE_WARN,
			    MYNAME
			    ": can't find reg entry for memory");
			error = DDI_FAILURE;
			goto fail;
		}
	} else if (STREQ(parent_type, "pci") || STREQ(parent_type, "pciex")) {
		pci_pcie_bus = 1;
		reg_rnumber = vgatext_get_pci_reg_index(devi,
		    PCI_REG_ADDR_M|PCI_REG_REL_M,
		    PCI_ADDR_IO|PCI_RELOCAT_B, VGA_REG_ADDR,
		    &reg_offset);
		if (reg_rnumber < 0) {
			cmn_err(CE_WARN,
			    MYNAME
			    ": can't find reg entry for registers");
			error = DDI_FAILURE;
			goto fail;
		}
		softc->fb_regno = vgatext_get_pci_reg_index(devi,
		    PCI_REG_ADDR_M|PCI_REG_REL_M,
		    PCI_ADDR_MEM32|PCI_RELOCAT_B, VGA_MEM_ADDR,
		    &mem_offset);
		if (softc->fb_regno < 0) {
			cmn_err(CE_WARN,
			    MYNAME
			    ": can't find reg entry for memory");
			error = DDI_FAILURE;
			goto fail;
		}
	} else {
		cmn_err(CE_WARN, MYNAME ": unknown parent type \"%s\".",
		    parent_type);
		error = DDI_FAILURE;
		goto fail;
	}
	ddi_prop_free(parent_type);
	parent_type = NULL;

	error = ddi_regs_map_setup(devi, reg_rnumber,
	    (caddr_t *)&softc->regs.addr, reg_offset, VGA_REG_SIZE,
	    &dev_attr, &softc->regs.handle);
	if (error != DDI_SUCCESS)
		goto fail;
	softc->regs.mapped = B_TRUE;

	softc->fb_size = VGA_MEM_SIZE;

	error = ddi_regs_map_setup(devi, softc->fb_regno,
	    (caddr_t *)&softc->fb.addr,
	    mem_offset, softc->fb_size,
	    &dev_attr, &softc->fb.handle);
	if (error != DDI_SUCCESS)
		goto fail;
	softc->fb.mapped = B_TRUE;

	if (ddi_get8(softc->regs.handle,
	    softc->regs.addr + VGA_MISC_R) & VGA_MISC_IOA_SEL)
		softc->text_base = (caddr_t)softc->fb.addr + VGA_COLOR_BASE;
	else
		softc->text_base = (caddr_t)softc->fb.addr + VGA_MONO_BASE;

	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
	    DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) {
		if (strcmp(cons, "graphics") == 0) {
			happyface_boot = 1;
			vgatext_silent = 1;
			softc->current_base = softc->shadow;
		} else {
			softc->current_base = softc->text_base;
		}
		ddi_prop_free(cons);
	} else {
		softc->current_base = softc->text_base;
	}

	error = ddi_prop_create(makedevice(DDI_MAJOR_T_UNKNOWN, unit),
	    devi, DDI_PROP_CANSLEEP, DDI_KERNEL_IOCTL, NULL, 0);
	if (error != DDI_SUCCESS)
		goto fail;

	gfxp_check_for_console(devi, softc, pci_pcie_bus);

	value = GFXP_IS_CONSOLE(softc) ? 1 : 0;
	if (ddi_prop_update_int(DDI_DEV_T_NONE, devi,
	    "primary-controller", value) != DDI_SUCCESS) {
		cmn_err(CE_WARN,
		    "Can not %s primary-controller "
		    "property for driver", value ? "set" : "clear");
	}

	/* only do this if not in graphics mode */
	if ((vgatext_silent == 0) && (GFXP_IS_CONSOLE(softc))) {
		vgatext_init(softc);
		vgatext_save_colormap(softc);
	}

	return (DDI_SUCCESS);

fail:
	if (parent_type != NULL)
		ddi_prop_free(parent_type);
	(void) gfxp_vgatext_detach(devi, DDI_DETACH, (void *)softc);
	return (error);
}
示例#21
0
/**
 * At attach time, we allocate the soft state structure for the current
 * instance of the device.
 */
static int quantis_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
  int instance;
  quantis_soft_state_t *soft_state;
  ddi_device_acc_attr_t dev_acc_attr; /* Hold the device access attributes. */
  int nregs;
  off_t regsize;
  char msg[MAX_MSG_LEN];

  LOG_DEBUG0("attach\n");

  switch (cmd)
  {
    case DDI_ATTACH:
      instance = ddi_get_instance(dip);
      snprintf(msg,
               MAX_MSG_LEN,
               "Attaching the Quantis device %d.\n",
               instance);
      LOG_DEBUG0(msg);

      /*
       * PCI devices are self-identifying devices, so we check that we
       * indeed have a Quantis QRNG card by checking that we have one
       * register page with the correct size.
       */
      if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS)
      {
        snprintf(msg,
                 MAX_MSG_LEN,
                 "Could not get the number of register for the Quantis device %d.\n",
                 instance);
        QUANTIS_ERROR(msg);
        return DDI_FAILURE;
      }

      if (nregs < 4)
      {
        snprintf(msg,
                 MAX_MSG_LEN,
                 "The Quantis device %d has %d PCI base registers, but should have at least 4.\n",
                 instance,
                 nregs);
        QUANTIS_ERROR(msg);
        return DDI_FAILURE;
      }

      if (ddi_dev_regsize(dip, QUANTIS_REG_IDX, &regsize) != DDI_SUCCESS)
      {
        snprintf(msg,
                 MAX_MSG_LEN,
                 "Could not get the register size for the Quantis device %d.\n",
                 instance);
        QUANTIS_ERROR(msg);
        return DDI_FAILURE;
      }

      if (regsize < (int)QUANTIS_REG_LENGTH)
      {
        snprintf(msg,
                 MAX_MSG_LEN,
                 "The size of the Quantice device (%d) registers file is %d bytes long, "
                 "but should be at least %u bytes long.\n",
                 instance,
                 (int)regsize,
                 (unsigned int)QUANTIS_REG_LENGTH);
        QUANTIS_ERROR(msg);
        return DDI_FAILURE;
      }

      LOG_DEBUG0("After test of the validity of the card, before soft state alloc.\n");
      if (ddi_soft_state_zalloc(quantis_soft_state_p, instance) != DDI_SUCCESS)
      {
        snprintf(msg,
                 MAX_MSG_LEN,
                 "Could not allocate soft state structure for the Quantis device %d.\n",
                 instance);
        QUANTIS_ERROR(msg);
        return DDI_FAILURE;
      }

      soft_state = (quantis_soft_state_t *)ddi_get_soft_state(quantis_soft_state_p,
                                                              instance);
      soft_state->dip = dip;
      ddi_set_driver_private(dip, (caddr_t)soft_state);
      soft_state->cnt = 0;

      /*
       * Initialize the mutex in the soft state. We have no interrupt,
       * so we can set `arg' to `NULL'
       */
      mutex_init(&soft_state->mutex, NULL, MUTEX_DRIVER, NULL);

      if (ddi_create_minor_node(dip,
                                ddi_get_name(dip),
                                S_IFCHR,
                                instance,
                                DDI_PSEUDO,
                                0) == DDI_FAILURE)
      {
        snprintf(msg,
                 MAX_MSG_LEN,
                 "Could not create minor node for the Quantis device %d.\n",
                 instance);
        QUANTIS_ERROR(msg);
        mutex_destroy(&soft_state->mutex);
        ddi_soft_state_free(quantis_soft_state_p, instance);
        return DDI_FAILURE;
      }
      LOG_DEBUG1("ddi_get_name %s\n", ddi_get_name(dip));

      dev_acc_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
      dev_acc_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
      dev_acc_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;

      if (ddi_regs_map_setup(dip,
                             QUANTIS_REG_IDX,
                             (caddr_t *)&soft_state->regs,
                             0,
                             QUANTIS_REG_LENGTH,
                             &dev_acc_attr,
                             &soft_state->regs_handle) != DDI_SUCCESS)
      {
        snprintf(msg,
                 MAX_MSG_LEN,
                 "Could not map the registers space of the Quantis device %d.\n",
                 instance);
        QUANTIS_ERROR(msg);
        mutex_destroy(&soft_state->mutex);
        ddi_soft_state_free(quantis_soft_state_p, instance);
        return DDI_FAILURE;
      }

      mutex_enter(&quantis_mutex);
      card_count++;
      mutex_exit(&quantis_mutex);

      LOG_DEBUG0("Just before mutex\n");
      mutex_enter(&soft_state->mutex);
      LOG_DEBUG0("Just before rng_reset.\n");
      quantis_rng_reset(soft_state);
      LOG_DEBUG0("Just before enable_modules.\n");
      quantis_rng_enable_modules(soft_state, quantis_rng_modules_mask(soft_state));
      LOG_DEBUG0("Just before release mutex.\n");
      mutex_exit(&soft_state->mutex);

      snprintf(msg,
               MAX_MSG_LEN,
               "Successfully attached the Quantis device %d. Currently, %d Quantis cards are available.\n",
               instance,
               card_count);
      QUANTIS_INFO(msg);

#     ifdef DEBUG
        ddi_report_dev(dip);
#     endif

      return DDI_SUCCESS;

    case DDI_SUSPEND:
    case DDI_PM_SUSPEND:
      return DDI_SUCCESS;

    default:
      return DDI_FAILURE;
  }
}
示例#22
0
/*
 * Autoconfiguration entry points.
 */
int
efe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	ddi_acc_handle_t pci;
	int types;
	int count;
	int actual;
	uint_t pri;
	efe_t *efep;
	mac_register_t *macp;

	switch (cmd) {
	case DDI_ATTACH:
		break;

	case DDI_RESUME:
		efep = ddi_get_driver_private(dip);
		return (efe_resume(efep));

	default:
		return (DDI_FAILURE);
	}

	/*
	 * PCI configuration.
	 */
	if (pci_config_setup(dip, &pci) != DDI_SUCCESS) {
		efe_error(dip, "unable to setup PCI configuration!");
		return (DDI_FAILURE);
	}

	pci_config_put16(pci, PCI_CONF_COMM,
	    pci_config_get16(pci, PCI_CONF_COMM) | PCI_COMM_MAE | PCI_COMM_ME);

	pci_config_teardown(&pci);

	if (ddi_intr_get_supported_types(dip, &types)
	    != DDI_SUCCESS || !(types & DDI_INTR_TYPE_FIXED)) {
		efe_error(dip, "fixed interrupts not supported!");
		return (DDI_FAILURE);
	}

	if (ddi_intr_get_nintrs(dip, DDI_INTR_TYPE_FIXED, &count)
	    != DDI_SUCCESS || count != 1) {
		efe_error(dip, "no fixed interrupts available!");
		return (DDI_FAILURE);
	}

	/*
	 * Initialize soft state.
	 */
	efep = kmem_zalloc(sizeof (efe_t), KM_SLEEP);
	ddi_set_driver_private(dip, efep);

	efep->efe_dip = dip;

	if (ddi_regs_map_setup(dip, 1, (caddr_t *)&efep->efe_regs, 0, 0,
	    &efe_regs_acc_attr, &efep->efe_regs_acch) != DDI_SUCCESS) {
		efe_error(dip, "unable to setup register mapping!");
		goto failure;
	}

	efep->efe_rx_ring = efe_ring_alloc(efep->efe_dip, RXDESCL);
	if (efep->efe_rx_ring == NULL) {
		efe_error(efep->efe_dip, "unable to allocate rx ring!");
		goto failure;
	}

	efep->efe_tx_ring = efe_ring_alloc(efep->efe_dip, TXDESCL);
	if (efep->efe_tx_ring == NULL) {
		efe_error(efep->efe_dip, "unable to allocate tx ring!");
		goto failure;
	}

	if (ddi_intr_alloc(dip, &efep->efe_intrh, DDI_INTR_TYPE_FIXED, 0,
	    count, &actual, DDI_INTR_ALLOC_STRICT) != DDI_SUCCESS ||
	    actual != count) {
		efe_error(dip, "unable to allocate fixed interrupt!");
		goto failure;
	}

	if (ddi_intr_get_pri(efep->efe_intrh, &pri) != DDI_SUCCESS ||
	    pri >= ddi_intr_get_hilevel_pri()) {
		efe_error(dip, "unable to get valid interrupt priority!");
		goto failure;
	}

	mutex_init(&efep->efe_intrlock, NULL, MUTEX_DRIVER,
	    DDI_INTR_PRI(pri));

	mutex_init(&efep->efe_txlock, NULL, MUTEX_DRIVER,
	    DDI_INTR_PRI(pri));

	/*
	 * Initialize device.
	 */
	mutex_enter(&efep->efe_intrlock);
	mutex_enter(&efep->efe_txlock);

	efe_reset(efep);

	mutex_exit(&efep->efe_txlock);
	mutex_exit(&efep->efe_intrlock);

	/* Use factory address as default */
	efe_getaddr(efep, efep->efe_macaddr);

	/*
	 * Enable the ISR.
	 */
	if (ddi_intr_add_handler(efep->efe_intrh, efe_intr, efep, NULL)
	    != DDI_SUCCESS) {
		efe_error(dip, "unable to add interrupt handler!");
		goto failure;
	}

	if (ddi_intr_enable(efep->efe_intrh) != DDI_SUCCESS) {
		efe_error(dip, "unable to enable interrupt!");
		goto failure;
	}

	/*
	 * Allocate MII resources.
	 */
	if ((efep->efe_miih = mii_alloc(efep, dip, &efe_mii_ops)) == NULL) {
		efe_error(dip, "unable to allocate mii resources!");
		goto failure;
	}

	/*
	 * Allocate MAC resources.
	 */
	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
		efe_error(dip, "unable to allocate mac resources!");
		goto failure;
	}

	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
	macp->m_driver = efep;
	macp->m_dip = dip;
	macp->m_src_addr = efep->efe_macaddr;
	macp->m_callbacks = &efe_m_callbacks;
	macp->m_min_sdu = 0;
	macp->m_max_sdu = ETHERMTU;
	macp->m_margin = VLAN_TAGSZ;

	if (mac_register(macp, &efep->efe_mh) != 0) {
		efe_error(dip, "unable to register with mac!");
		goto failure;
	}
	mac_free(macp);

	ddi_report_dev(dip);

	return (DDI_SUCCESS);

failure:
	if (macp != NULL) {
		mac_free(macp);
	}

	if (efep->efe_miih != NULL) {
		mii_free(efep->efe_miih);
	}

	if (efep->efe_intrh != NULL) {
		(void) ddi_intr_disable(efep->efe_intrh);
		(void) ddi_intr_remove_handler(efep->efe_intrh);
		(void) ddi_intr_free(efep->efe_intrh);
	}

	mutex_destroy(&efep->efe_txlock);
	mutex_destroy(&efep->efe_intrlock);

	if (efep->efe_tx_ring != NULL) {
		efe_ring_free(&efep->efe_tx_ring);
	}
	if (efep->efe_rx_ring != NULL) {
		efe_ring_free(&efep->efe_rx_ring);
	}

	if (efep->efe_regs_acch != NULL) {
		ddi_regs_map_free(&efep->efe_regs_acch);
	}

	kmem_free(efep, sizeof (efe_t));

	return (DDI_FAILURE);
}
示例#23
0
/*
 * heci_probe - Device Initialization Routine
 */
static int
heci_initialize(dev_info_t *dip, struct iamt_heci_device *device)
{
	int err;
	ddi_device_acc_attr_t attr;

	err = ddi_get_iblock_cookie(dip, 0, &device->sc_iblk);
	if (err != DDI_SUCCESS) {
		cmn_err(CE_WARN, "heci_probe():"
		    " ddi_get_iblock_cookie() failed\n");
		goto end;
	}
	/* initializes the heci device structure */
	init_heci_device(dip, device);

	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
	attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;

	if (ddi_regs_map_setup(dip, 1, (caddr_t *)&device->mem_addr, 0, 0,
	    &attr, &device->io_handle) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "heci%d: unable to map PCI regs\n",
		    ddi_get_instance(dip));
		goto fini_heci_device;
	}

	err = ddi_add_intr(dip, 0, &device->sc_iblk, NULL,
	    heci_isr_interrupt, (caddr_t)device);
	if (err != DDI_SUCCESS) {
		cmn_err(CE_WARN, "heci_probe(): ddi_add_intr() failed\n");
		goto unmap_memory;
	}

	if (heci_hw_init(device)) {
		cmn_err(CE_WARN, "init hw failure.\n");
		err = -ENODEV;
		goto release_irq;
	}
	(void) heci_initialize_clients(device);
	if (device->heci_state != HECI_ENABLED) {
		err = -ENODEV;
		goto release_hw;
	}
	if (device->wd_timeout)
		device->wd_timer = timeout(heci_wd_timer, device, 1);

	DBG("heci driver initialization successful.\n");
	return (0);

release_hw:
	/* disable interrupts */
	device->host_hw_state = read_heci_register(device, H_CSR);
	heci_csr_disable_interrupts(device);

release_irq:
	ddi_remove_intr(dip, 0, device->sc_iblk);
unmap_memory:
	if (device->mem_addr)
		ddi_regs_map_free(&device->io_handle);
fini_heci_device:
	fini_heci_device(device);
end:
	cmn_err(CE_WARN, "heci driver initialization failed.\n");
	return (err);
}