/*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); } }
/* * 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); }
/* * 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); }
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); }
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); }
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); }
/* * 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); }
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); }