Example #1
0
/*ARGSUSED*/
static int
logiattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	int unit;
	struct driver_minor_data *dmdp;
	struct strmseinfo *logiptr = 0;

#ifdef LOGI_DEBUG
	if (logi_debug) {
		PRF("logiattach entry\n");
	}
#endif
	switch (cmd) {
	case DDI_ATTACH:
		unit = ddi_get_instance(dip);

		for (dmdp = logi_minor_data; dmdp->name != NULL; dmdp++) {
			if (ddi_create_minor_node(dip, dmdp->name, dmdp->type,
			    dmdp->minor, DDI_PSEUDO, NULL) == DDI_FAILURE) {

				ddi_remove_minor_node(dip, NULL);
				ddi_prop_remove_all(dip);
#ifdef LOGI_DEBUG
				if (logi_debug)
					PRF("logiattach: "
					    "ddi_create_minor_node failed\n");
#endif
				return (DDI_FAILURE);
			}
		}
		logiunits[unit] = dip;
		/* allocate and initialize state structure */
		logiptr = kmem_zalloc(sizeof (struct strmseinfo), KM_SLEEP);
		logiptr->state = 0;	/* not opened */
		ddi_set_driver_private(dip, logiptr);


		if (ddi_add_intr(dip, (uint_t)0, &logiptr->iblock,
		    (ddi_idevice_cookie_t *)0, logiintr,
		    (caddr_t)logiptr) != DDI_SUCCESS) {

#ifdef LOGI_DEBUG
			if (logi_debug)
				PRF("logiattach: ddi_add_intr failed\n");
#endif
			cmn_err(CE_WARN, "logi: cannot add intr\n");
			return (DDI_FAILURE);
		}

		mutex_init(&logiptr->lock, NULL, MUTEX_DRIVER,
		    (void *)logiptr->iblock);
		ddi_report_dev(dip);
		return (DDI_SUCCESS);
	default:
		return (DDI_FAILURE);
	}
}
Example #2
0
/*
 * hci1394_isr_handler_init()
 *    register our interrupt service routine.
 */
int
hci1394_isr_handler_init(hci1394_state_t *soft_state)
{
	int status;

	ASSERT(soft_state != NULL);

	/* Initialize interrupt handler */
	status = ddi_add_intr(soft_state->drvinfo.di_dip, 0, NULL, NULL,
	    hci1394_isr, (caddr_t)soft_state);
	if (status != DDI_SUCCESS) {
		TNF_PROBE_0(hci1394_isr_handler_init_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		return (DDI_FAILURE);
	}

	return (DDI_SUCCESS);
}
Example #3
0
/*
 * Add interrupt handlers
 */
int
sbbc_add_intr(sbbc_softstate_t *softsp)
{
	int		rc = DDI_SUCCESS;

	/*
	 * map in the SBBC interrupts
	 * Note that the iblock_cookie was initialised
	 * in the 'attach' routine
	 */

	if (ddi_add_intr(softsp->dip, 0, &softsp->iblock,
		&softsp->idevice, sbbc_intr_handler,
		(caddr_t)softsp) != DDI_SUCCESS) {

		cmn_err(CE_WARN, "Can't register SBBC "
			" interrupt handler\n");
		rc = DDI_FAILURE;
	}

	return (rc);
}
Example #4
0
int
ghd_register(char *labelp,
	ccc_t	*cccp,
	dev_info_t *dip,
	int	inumber,
	void	*hba_handle,
	int	(*ccballoc)(gtgt_t *, gcmd_t *, int, int, int, int),
	void	(*ccbfree)(gcmd_t *),
	void	(*sg_func)(gcmd_t *, ddi_dma_cookie_t *, int, int),
	int	(*hba_start)(void *, gcmd_t *),
	void    (*hba_complete)(void *, gcmd_t *, int),
	uint_t	(*int_handler)(caddr_t),
	int	(*get_status)(void *, void *),
	void	(*process_intr)(void *, void *),
	int	(*timeout_func)(void *, gcmd_t *, gtgt_t *, gact_t, int),
	tmr_t	*tmrp,
	void 	(*hba_reset_notify_callback)(gtgt_t *,
			void (*)(caddr_t), caddr_t))
{

	cccp->ccc_label = labelp;
	cccp->ccc_hba_dip = dip;
	cccp->ccc_ccballoc = ccballoc;
	cccp->ccc_ccbfree = ccbfree;
	cccp->ccc_sg_func = sg_func;
	cccp->ccc_hba_start = hba_start;
	cccp->ccc_hba_complete = hba_complete;
	cccp->ccc_process_intr = process_intr;
	cccp->ccc_get_status = get_status;
	cccp->ccc_hba_handle = hba_handle;
	cccp->ccc_hba_reset_notify_callback = hba_reset_notify_callback;

	/* initialize the HBA's list headers */
	CCCP_INIT(cccp);

	if (ddi_get_iblock_cookie(dip, inumber, &cccp->ccc_iblock)
	    != DDI_SUCCESS) {

		return (FALSE);
	}

	mutex_init(&cccp->ccc_hba_mutex, NULL, MUTEX_DRIVER, cccp->ccc_iblock);

	mutex_init(&cccp->ccc_waitq_mutex, NULL, MUTEX_DRIVER,
	    cccp->ccc_iblock);

	mutex_init(&cccp->ccc_reset_notify_mutex, NULL, MUTEX_DRIVER,
	    cccp->ccc_iblock);

	/* Establish interrupt handler */
	if (ddi_add_intr(dip, inumber, &cccp->ccc_iblock, NULL,
	    int_handler, (caddr_t)hba_handle) != DDI_SUCCESS) {
		mutex_destroy(&cccp->ccc_hba_mutex);
		mutex_destroy(&cccp->ccc_waitq_mutex);
		mutex_destroy(&cccp->ccc_reset_notify_mutex);

		return (FALSE);
	}

	if (ghd_timer_attach(cccp, tmrp, timeout_func) == FALSE) {
		ddi_remove_intr(cccp->ccc_hba_dip, 0, cccp->ccc_iblock);
		mutex_destroy(&cccp->ccc_hba_mutex);
		mutex_destroy(&cccp->ccc_waitq_mutex);
		mutex_destroy(&cccp->ccc_reset_notify_mutex);

		return (FALSE);
	}

	if (ghd_doneq_init(cccp)) {

		return (TRUE);
	}

	/*
	 * ghd_doneq_init() returned error:
	 */

	ghd_timer_detach(cccp);
	ddi_remove_intr(cccp->ccc_hba_dip, 0, cccp->ccc_iblock);
	mutex_destroy(&cccp->ccc_hba_mutex);
	mutex_destroy(&cccp->ccc_waitq_mutex);
	mutex_destroy(&cccp->ccc_reset_notify_mutex);

	return (FALSE);

}
Example #5
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);
}
Example #6
0
int
rmc_comm_serdev_init(struct rmc_comm_state *rcs, dev_info_t *dip)
{
	cyc_handler_t cychand;
	cyc_time_t cyctime;
	int err = DDI_SUCCESS;

	rcs->sd_state.cycid = CYCLIC_NONE;

	/*
	 *  Online the hardware ...
	 */
	err = rmc_comm_online(rcs, dip);
	if (err != 0)
		return (-1);

	/*
	 * call ddi_get_soft_iblock_cookie() to retrieve the
	 * the interrupt block cookie so that the mutexes are initialized
	 * before adding the interrupt (to avoid a potential race condition).
	 */

	err = ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_LOW,
	    &rcs->dp_state.dp_iblk);
	if (err != DDI_SUCCESS)
		return (-1);

	err = ddi_get_iblock_cookie(dip, 0, &rcs->sd_state.hw_iblk);
	if (err != DDI_SUCCESS)
		return (-1);

	/*
	 * initialize mutex here before adding hw/sw interrupt handlers
	 */
	mutex_init(rcs->dp_state.dp_mutex, NULL, MUTEX_DRIVER,
	    rcs->dp_state.dp_iblk);

	mutex_init(rcs->sd_state.hw_mutex, NULL, MUTEX_DRIVER,
	    rcs->sd_state.hw_iblk);

	/*
	 * Install soft and hard interrupt handler(s)
	 *
	 * the soft intr. handler will need the data protocol lock (dp_mutex)
	 * So, data protocol mutex and iblock cookie are created/initialized
	 * here
	 */

	err = ddi_add_softintr(dip, DDI_SOFTINT_LOW, &rcs->sd_state.softid,
	    &rcs->dp_state.dp_iblk, NULL, rmc_comm_softint, (caddr_t)rcs);
	if (err != DDI_SUCCESS) {
		mutex_destroy(rcs->dp_state.dp_mutex);
		mutex_destroy(rcs->sd_state.hw_mutex);
		return (-1);
	}

	/*
	 * hardware interrupt
	 */

	if (rcs->sd_state.sio_handle != NULL) {
		err = ddi_add_intr(dip, 0, &rcs->sd_state.hw_iblk, NULL,
			rmc_comm_hi_intr, (caddr_t)rcs);

		/*
		 * did we successfully install the h/w interrupt handler?
		 */
		if (err != DDI_SUCCESS) {
			ddi_remove_softintr(rcs->sd_state.softid);
			mutex_destroy(rcs->dp_state.dp_mutex);
			mutex_destroy(rcs->sd_state.hw_mutex);
			return (-1);
		}
	}


	/*
	 * Start cyclic callbacks
	 */

	cychand.cyh_func = rmc_comm_cyclic;
	cychand.cyh_arg = rcs;
	cychand.cyh_level = CY_LOW_LEVEL;
	cyctime.cyt_when = 0;			/* from the next second	*/
	cyctime.cyt_interval = 5*RMC_COMM_ONE_SEC; /* call at 5s intervals */
	mutex_enter(&cpu_lock);
	rcs->sd_state.cycid = cyclic_add(&cychand, &cyctime);
	mutex_exit(&cpu_lock);

	return (0);
}
static int
ds1287_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	struct ds1287 *softsp;

	DPRINTF("ds1287_attach\n");
	switch (cmd) {
	case DDI_ATTACH:
		break;
	case DDI_RESUME:
		return (DDI_SUCCESS);
	default:
		return (DDI_FAILURE);
	}

	if (instance != -1) {
		cmn_err(CE_WARN, "ds1287_attach: Another instance is already "
		    "attached.");
		return (DDI_FAILURE);
	}

	instance = ddi_get_instance(dip);

	if (v_rtc_addr_reg == NULL) {
		cmn_err(CE_WARN, "ds1287_attach: v_rtc_addr_reg is NULL");
		return (DDI_FAILURE);
	}

	/*
	 * Allocate softc information.
	 */
	if (ddi_soft_state_zalloc(ds1287_state, instance) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "ds1287_attach: Failed to allocate "
		    "soft states.");
		return (DDI_FAILURE);
	}

	softsp = ddi_get_soft_state(ds1287_state, instance);
	DPRINTF("ds1287_attach: instance=%d softsp=0x%p\n", instance,
	    (void *)softsp);

	softsp->dip = dip;

	if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
	    "interrupt-priorities", (caddr_t)&ds1287_interrupt_priority,
	    sizeof (int)) != DDI_PROP_SUCCESS) {
		cmn_err(CE_WARN, "ds1287_attach: Failed to create \""
		    "interrupt-priorities\" property.");
		goto error;
	}

	/* add the softint */
	ds1287_lo_iblock = (ddi_iblock_cookie_t)(uintptr_t)
	    ipltospl(ds1287_softint_priority);

	if (ddi_add_softintr(dip, DDI_SOFTINT_FIXED, &ds1287_softintr_id,
	    &ds1287_lo_iblock, NULL, ds1287_softintr, (caddr_t)softsp) !=
	    DDI_SUCCESS) {
		cmn_err(CE_WARN, "ds1287_attach: Failed to add low interrupt.");
		goto error1;
	}

	/* add the hi interrupt */
	if (ddi_add_intr(dip, 0, NULL, (ddi_idevice_cookie_t *)
	    &ds1287_hi_iblock, ds1287_intr, NULL) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "ds1287_attach: Failed to add high "
		    "interrupt.");
		goto error2;
	}

	/*
	 * Combination of instance number and clone number 0 is used for
	 * creating the minor node.
	 */
	if (ddi_create_minor_node(dip, "power_button", S_IFCHR,
	    (instance << 8) + 0, "ddi_power_button", NULL) == DDI_FAILURE) {
		cmn_err(CE_WARN, "ds1287_attach: Failed to create minor node");
		goto error3;
	}

	ddi_report_dev(dip);

	return (DDI_SUCCESS);

error3:
	ddi_remove_intr(dip, 0, NULL);
error2:
	ddi_remove_softintr(ds1287_softintr_id);
error1:
	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "interrupt-priorities");
error:
	ddi_soft_state_free(ds1287_state, instance);
	return (DDI_FAILURE);
}
Example #8
0
/*
 * attach(9E) -- Attach a device to the system
 *
 * Called once for each board successfully probed.
 */
static int
SMCG_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
{
	gld_mac_info_t	*macinfo;
	Adapter_Struc	*pAd;
	smcg_t		*smcg;
	int		rc;
	ddi_acc_handle_t pcihandle;

#ifdef	DEBUG
	if (SMCG_debug & SMCGDDI)
		cmn_err(CE_CONT, SMCG_NAME "_attach(0x%p)", (void *)devinfo);
#endif

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

	/*
	 * Allocate gld_mac_info_t and Lower MAC Adapter_Struc structures
	 */
	if ((macinfo = gld_mac_alloc(devinfo)) == NULL)
		return (DDI_FAILURE);
	if ((pAd = kmem_zalloc(sizeof (Adapter_Struc), KM_NOSLEEP)) == NULL) {
		gld_mac_free(macinfo);
		return (DDI_FAILURE);
	}
	if ((smcg = kmem_zalloc(sizeof (smcg_t), KM_NOSLEEP)) == NULL) {
		gld_mac_free(macinfo);
		kmem_free(pAd, sizeof (Adapter_Struc));
		return (DDI_FAILURE);
	}

	pAd->pc_bus = SMCG_PCI_BUS;

	/* create pci handle for UM_PCI_Service */
	if (pci_config_setup(devinfo, (ddi_acc_handle_t *)&pcihandle)
	    != DDI_SUCCESS) {
		goto attach_fail_cleanup;
	}

	/*
	 * Query the LMAC for the device information
	 */
	pAd->pcihandle = (void *) pcihandle;
	rc = LM_GetCnfg(pAd);

	pci_config_teardown((ddi_acc_handle_t *)&pcihandle);
	pAd->pcihandle = NULL;

	if (rc != ADAPTER_AND_CONFIG) {
		cmn_err(CE_WARN,
		    SMCG_NAME "_attach: LM_GetCnfg failed (0x%x)", rc);
		goto attach_fail_cleanup;
	}

	/*
	 * Initialize pointers to device specific functions which will be
	 * used by the generic layer.
	 */
	macinfo->gldm_reset   = SMCG_reset;
	macinfo->gldm_start   = SMCG_start_board;
	macinfo->gldm_stop    = SMCG_stop_board;
	macinfo->gldm_set_mac_addr   = SMCG_set_mac_addr;
	macinfo->gldm_set_multicast = SMCG_set_multicast;
	macinfo->gldm_set_promiscuous = SMCG_set_promiscuous;
	macinfo->gldm_get_stats   = SMCG_get_stats;
	macinfo->gldm_send    = SMCG_send;
	macinfo->gldm_intr    = SMCG_intr;
	macinfo->gldm_ioctl   = NULL;

	/*
	 * Initialize board characteristics needed by the generic layer.
	 */
	macinfo->gldm_ident = SMCG_IDENT;
	macinfo->gldm_type = DL_ETHER;
	macinfo->gldm_minpkt = 0;	/* assumes we pad ourselves */
	macinfo->gldm_maxpkt = SMCGMAXPKT;
	macinfo->gldm_addrlen = ETHERADDRL;
	macinfo->gldm_saplen = -2;
	macinfo->gldm_ppa = ddi_get_instance(devinfo);

	pAd->receive_mask = ACCEPT_BROADCAST;
	pAd->max_packet_size = SMMAXPKT;

	macinfo->gldm_broadcast_addr = SMCG_broadcastaddr;

	/* Get the board's vendor-assigned hardware network address. */
	LM_Get_Addr(pAd);
	macinfo->gldm_vendor_addr = (unsigned char *)pAd->node_address;

	/* Link macinfo, smcg, and LMAC Adapter Structs */
	macinfo->gldm_private = (caddr_t)smcg;
	pAd->sm_private = (void *)smcg;
	smcg->smcg_pAd = pAd;
	smcg->smcg_macinfo = macinfo;

	pAd->ptr_rx_CRC_errors = &smcg->rx_CRC_errors;
	pAd->ptr_rx_too_big = &smcg->rx_too_big;
	pAd->ptr_rx_lost_pkts = &smcg->rx_lost_pkts;
	pAd->ptr_rx_align_errors = &smcg->rx_align_errors;
	pAd->ptr_rx_overruns = &smcg->rx_overruns;
	pAd->ptr_tx_deferred = &smcg->tx_deferred;
	pAd->ptr_tx_total_collisions = &smcg->tx_total_collisions;
	pAd->ptr_tx_max_collisions = &smcg->tx_max_collisions;
	pAd->ptr_tx_one_collision = &smcg->tx_one_collision;
	pAd->ptr_tx_mult_collisions = &smcg->tx_mult_collisions;
	pAd->ptr_tx_ow_collision = &smcg->tx_ow_collision;
	pAd->ptr_tx_CD_heartbeat = &smcg->tx_CD_heartbeat;
	pAd->ptr_tx_carrier_lost = &smcg->tx_carrier_lost;
	pAd->ptr_tx_underruns = &smcg->tx_underruns;
	pAd->ptr_ring_OVW = &smcg->ring_OVW;

	macinfo->gldm_devinfo = smcg->smcg_devinfo = devinfo;

	pAd->num_of_tx_buffs = ddi_getprop(DDI_DEV_T_ANY, devinfo,
	    DDI_PROP_DONTPASS, "num-tx-bufs", SMTRANSMIT_BUFS);
	if (pAd->num_of_tx_buffs > SMCG_MAX_TXDESCS) {
		pAd->num_of_tx_buffs = SMCG_MAX_TXDESCS;
		cmn_err(CE_WARN, SMCG_NAME
		    "Max number_of_tx_buffs is %d", SMCG_MAX_TXDESCS);
	}
	if (pAd->num_of_tx_buffs < 2) {
		pAd->num_of_tx_buffs = 2;
	}
	pAd->num_of_rx_buffs = ddi_getprop(DDI_DEV_T_ANY, devinfo,
	    DDI_PROP_DONTPASS, "num-rx-bufs", SMRECEIVE_BUFS);
	if (pAd->num_of_rx_buffs > SMCG_MAX_RXDESCS) {
		pAd->num_of_rx_buffs = SMCG_MAX_RXDESCS;
		cmn_err(CE_WARN, SMCG_NAME
		    "Max number_of_rx_buffs is %d", SMCG_MAX_RXDESCS);
	}
	if (pAd->num_of_rx_buffs < 2) {
		pAd->num_of_rx_buffs = 2;
	}

	if (ddi_get_iblock_cookie(devinfo, 0, &macinfo->gldm_cookie)
		!= DDI_SUCCESS)
		goto attach_fail_cleanup;

	/*
	 * rbuf_lock	Protects receive data structures
	 * txbuf_lock	Protects transmit data structures
	 * lm_lock	Protects all calls to LMAC layer
	 * rlist_lock	Protects receive buffer list
	 * Note: Locks should be acquired in the above order.
	 */
	mutex_init(&smcg->rbuf_lock, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&smcg->txbuf_lock, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&smcg->lm_lock, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&smcg->rlist_lock, NULL, MUTEX_DRIVER, NULL);

	/*
	 * SMCG_dma_alloc is called before it is possible to get
	 * any interrupts, send or receive packets... Therefore I'm
	 * not going to take rlist_lock for it.
	 */
	if (SMCG_dma_alloc(smcg) != DDI_SUCCESS)
		goto attach_fail_cleanup1;

#ifdef SAFE
	LM_Reset_Adapter(pAd);
#endif
	/* Add the interrupt handler */
	if (ddi_add_intr(devinfo, 0,  NULL, NULL, gld_intr, (caddr_t)macinfo)
	    != DDI_SUCCESS) {
		SMCG_dma_unalloc(smcg);
		goto attach_fail_cleanup1;
	}

	/*
	 * Register ourselves with the GLD interface
	 *
	 * gld_register will:
	 *	link us with the GLD system;
	 *	create the minor node.
	 */
	if (gld_register(devinfo, SMCG_NAME, macinfo) != DDI_SUCCESS) {
		ddi_remove_intr(devinfo, 0, macinfo->gldm_cookie);
		SMCG_dma_unalloc(smcg);
		goto attach_fail_cleanup1;
	}

	return (DDI_SUCCESS);

attach_fail_cleanup1:
	mutex_destroy(&smcg->rbuf_lock);
	mutex_destroy(&smcg->txbuf_lock);
	mutex_destroy(&smcg->lm_lock);
	mutex_destroy(&smcg->rlist_lock);

attach_fail_cleanup:
	kmem_free(pAd, sizeof (Adapter_Struc));
	kmem_free(smcg, sizeof (smcg_t));
	gld_mac_free(macinfo);
	return (DDI_FAILURE);
}
/*
 * audioixp_attach()
 *
 * Description:
 *	Attach an instance of the audioixp driver. This routine does
 * 	the device dependent attach tasks.
 *
 * Arguments:
 *	dev_info_t	*dip	Pointer to the device's dev_info struct
 *	ddi_attach_cmd_t cmd	Attach command
 *
 * Returns:
 *	DDI_SUCCESS		The driver was initialized properly
 *	DDI_FAILURE		The driver couldn't be initialized properly
 */
static int
audioixp_attach(dev_info_t *dip)
{
	uint16_t		cmdeg;
	audioixp_state_t	*statep;
	audio_dev_t		*adev;
	uint32_t		devid;
	const char		*name;
	const char		*rev;

	/* we don't support high level interrupts in the driver */
	if (ddi_intr_hilevel(dip, 0) != 0) {
		cmn_err(CE_WARN,
		    "!%s%d: unsupported high level interrupt",
		    ddi_driver_name(dip), ddi_get_instance(dip));
		return (DDI_FAILURE);
	}

	/* allocate the soft state structure */
	statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
	statep->dip = dip;
	ddi_set_driver_private(dip, statep);

	if (ddi_get_iblock_cookie(dip, 0, &statep->iblock) != DDI_SUCCESS) {
		cmn_err(CE_WARN,
		    "!%s%d: cannot get iblock cookie",
		    ddi_driver_name(dip), ddi_get_instance(dip));
		kmem_free(statep, sizeof (*statep));
		return (DDI_FAILURE);
	}
	mutex_init(&statep->inst_lock, NULL, MUTEX_DRIVER, statep->iblock);

	/* allocate framework audio device */
	if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
		cmn_err(CE_WARN, "!%s%d: unable to allocate audio dev",
		    ddi_driver_name(dip), ddi_get_instance(dip));
		goto error;
	}
	statep->adev = adev;

	/* map in the registers */
	if (audioixp_map_regs(statep) != DDI_SUCCESS) {
		audio_dev_warn(adev, "couldn't map registers");
		goto error;
	}

	/* set device information -- this could be smarter */
	devid = ((pci_config_get16(statep->pcih, PCI_CONF_VENID)) << 16) |
	    pci_config_get16(statep->pcih, PCI_CONF_DEVID);

	name = "ATI AC'97";
	switch (devid) {
	case IXP_PCI_ID_200:
		rev = "IXP150";
		break;
	case IXP_PCI_ID_300:
		rev = "SB300";
		break;
	case IXP_PCI_ID_400:
		if (pci_config_get8(statep->pcih, PCI_CONF_REVID) & 0x80) {
			rev = "SB450";
		} else {
			rev = "SB400";
		}
		break;
	case IXP_PCI_ID_SB600:
		rev = "SB600";
		break;
	default:
		rev = "Unknown";
		break;
	}
	audio_dev_set_description(adev, name);
	audio_dev_set_version(adev, rev);

	/* allocate port structures */
	if ((audioixp_alloc_port(statep, IXP_PLAY) != DDI_SUCCESS) ||
	    (audioixp_alloc_port(statep, IXP_REC) != DDI_SUCCESS)) {
		goto error;
	}

	statep->ac97 = ac97_alloc(dip, audioixp_rd97, audioixp_wr97, statep);
	if (statep->ac97 == NULL) {
		audio_dev_warn(adev, "failed to allocate ac97 handle");
		goto error;
	}

	/* set PCI command register */
	cmdeg = pci_config_get16(statep->pcih, PCI_CONF_COMM);
	pci_config_put16(statep->pcih, PCI_CONF_COMM,
	    cmdeg | PCI_COMM_IO | PCI_COMM_MAE);

	/* set up kernel statistics */
	if ((statep->ksp = kstat_create(IXP_NAME, ddi_get_instance(dip),
	    IXP_NAME, "controller", KSTAT_TYPE_INTR, 1,
	    KSTAT_FLAG_PERSISTENT)) != NULL) {
		kstat_install(statep->ksp);
	}


	if (audioixp_chip_init(statep) != DDI_SUCCESS) {
		audio_dev_warn(statep->adev, "failed to init chip");
		goto error;
	}

	/* initialize the AC'97 part */
	if (ac97_init(statep->ac97, adev) != DDI_SUCCESS) {
		audio_dev_warn(adev, "ac'97 initialization failed");
		goto error;
	}

	/* set up the interrupt handler */
	if (ddi_add_intr(dip, 0, &statep->iblock, NULL, audioixp_intr,
	    (caddr_t)statep) != DDI_SUCCESS) {
		audio_dev_warn(adev, "bad interrupt specification");
	}
	statep->intr_added = B_TRUE;

	if (audio_dev_register(adev) != DDI_SUCCESS) {
		audio_dev_warn(adev, "unable to register with framework");
		goto error;
	}

	ddi_report_dev(dip);

	return (DDI_SUCCESS);

error:
	audioixp_destroy(statep);
	return (DDI_FAILURE);
}
Example #10
0
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);
}
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);
}
/*
 * 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);
}