static void pcn_teardown(pcn_t *pcnp) { ASSERT(!(pcnp->pcn_flags & PCN_RUNNING)); if (pcnp->pcn_mii != NULL) { mii_free(pcnp->pcn_mii); pcnp->pcn_mii = NULL; } if (pcnp->pcn_flags & PCN_INTR_ENABLED) ddi_remove_intr(pcnp->pcn_dip, 0, pcnp->pcn_icookie); /* These will exit gracefully if not yet allocated */ pcn_freerxring(pcnp); pcn_freetxring(pcnp); if (pcnp->pcn_regshandle != NULL) ddi_regs_map_free(&pcnp->pcn_regshandle); mutex_destroy(&pcnp->pcn_xmtlock); mutex_destroy(&pcnp->pcn_intrlock); mutex_destroy(&pcnp->pcn_reglock); ddi_soft_state_free(pcn_ssp, ddi_get_instance(pcnp->pcn_dip)); }
/*ARGSUSED*/ static int mouse8042_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { struct mouse_state *state; state = ddi_get_driver_private(dip); switch (cmd) { case DDI_SUSPEND: /* Ignore all data from mouse8042_intr until we fully resume */ state->ready = 0; return (DDI_SUCCESS); case DDI_DETACH: ddi_remove_intr(dip, 0, state->ms_iblock_cookie); mouse8042_dip = NULL; cv_destroy(&state->reset_cv); mutex_destroy(&state->reset_mutex); mutex_destroy(&state->ms_mutex); ddi_prop_remove_all(dip); ddi_regs_map_free(&state->ms_handle); ddi_remove_minor_node(dip, NULL); kmem_free(state, sizeof (struct mouse_state)); return (DDI_SUCCESS); default: return (DDI_FAILURE); } }
/* * hci1394_isr_handler_fini() * un-register our interrupt service routine. */ void hci1394_isr_handler_fini(hci1394_state_t *soft_state) { ASSERT(soft_state != NULL); /* Remove interrupt handler */ ddi_remove_intr(soft_state->drvinfo.di_dip, 0, soft_state->drvinfo.di_iblock_cookie); }
void ghd_unregister(ccc_t *cccp) { ghd_timer_detach(cccp); ddi_remove_intr(cccp->ccc_hba_dip, 0, cccp->ccc_iblock); ddi_remove_softintr(cccp->ccc_doneq_softid); mutex_destroy(&cccp->ccc_hba_mutex); mutex_destroy(&cccp->ccc_waitq_mutex); mutex_destroy(&cccp->ccc_doneq_mutex); }
/*ARGSUSED*/ static int logidetach(dev_info_t *dip, ddi_detach_cmd_t cmd) { dev_info_t *ldevi; struct strmseinfo *logiptr; int instance; switch (cmd) { case DDI_DETACH: /* * check if every instance can be unloaded before actually * starting to unload this one; this prevents the needless * detach/re-attach sequence */ for (instance = 0; instance < LOGI_MAXUNIT; instance++) { if (((ldevi = logiunits[instance]) == NULL) || (logiptr = ddi_get_driver_private(ldevi)) == NULL) continue; } /* * Undo what we did in logiattach & logiprobe, freeing resources * and removing things we installed. The system * framework guarantees we are not active with this devinfo * node in any other entry points at this time. */ instance = ddi_get_instance(dip); if ((instance >= LOGI_MAXUNIT) || (logiptr = ddi_get_driver_private(dip)) == NULL) return (DDI_FAILURE); logiunits[instance] = 0; ddi_prop_remove_all(dip); ddi_remove_minor_node(dip, NULL); mutex_destroy(&logiptr->lock); ddi_remove_intr(dip, 0, logiptr->iblock); kmem_free(logiptr, sizeof (struct strmseinfo)); return (DDI_SUCCESS); default: #ifdef LOGI_DEBUG if (logi_debug) { PRF("logidetach: cmd = %d unknown\n", cmd); } #endif return (DDI_FAILURE); } }
static void kb8042_cleanup(struct kb8042 *kb8042) { ASSERT(kb8042_dip != NULL); if (kb8042->init_state & KB8042_HW_MUTEX_INITTED) mutex_destroy(&kb8042->w_hw_mutex); if (kb8042->init_state & KB8042_INTR_ADDED) ddi_remove_intr(kb8042_dip, 0, kb8042->w_iblock); if (kb8042->init_state & KB8042_REGS_MAPPED) ddi_regs_map_free(&kb8042->handle); if (kb8042->init_state & KB8042_MINOR_NODE_CREATED) ddi_remove_minor_node(kb8042_dip, NULL); kb8042->init_state = KB8042_UNINITIALIZED; kb8042_dip = NULL; }
void rmc_comm_serdev_fini(struct rmc_comm_state *rcs, dev_info_t *dip) { rmc_comm_hw_reset(rcs); if (rcs->sd_state.cycid != CYCLIC_NONE) { mutex_enter(&cpu_lock); cyclic_remove(rcs->sd_state.cycid); mutex_exit(&cpu_lock); if (rcs->sd_state.sio_handle != NULL) ddi_remove_intr(dip, 0, rcs->sd_state.hw_iblk); ddi_remove_softintr(rcs->sd_state.softid); mutex_destroy(rcs->sd_state.hw_mutex); mutex_destroy(rcs->dp_state.dp_mutex); } rmc_comm_offline(rcs); }
/* * audioixp_destroy() * * Description: * This routine releases all resources held by the device instance, * as part of either detach or a failure in attach. * * Arguments: * audioixp_state_t *state The device soft state. */ void audioixp_destroy(audioixp_state_t *statep) { if (!statep->suspended) { PUT32(IXP_AUDIO_INT, GET32(IXP_AUDIO_INT)); PUT32(IXP_AUDIO_INT_EN, 0); /* * put the audio controller into quiet state, everything off */ CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA); CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA); } if (statep->intr_added) { ddi_remove_intr(statep->dip, 0, statep->iblock); } if (statep->ksp) { kstat_delete(statep->ksp); } audioixp_free_port(statep->play_port); audioixp_free_port(statep->rec_port); audioixp_unmap_regs(statep); if (statep->ac97) { ac97_free(statep->ac97); } if (statep->adev) { audio_dev_free(statep->adev); } mutex_destroy(&statep->inst_lock); kmem_free(statep, sizeof (*statep)); }
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); }
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); }
/* detach(9E) -- Detach a device from the system */ static int SMCG_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) { gld_mac_info_t *macinfo; Adapter_Struc *pAd; smcg_t *smcg; int i; #ifdef DEBUG if (SMCG_debug & SMCGDDI) cmn_err(CE_CONT, SMCG_NAME "_detach(0x%p)", (void *)devinfo); #endif if (cmd != DDI_DETACH) return (DDI_FAILURE); macinfo = ddi_get_driver_private(devinfo); smcg = (smcg_t *)macinfo->gldm_private; pAd = smcg->smcg_pAd; i = 50; mutex_enter(&smcg->rlist_lock); while (smcg->rx_bufs_outstanding > 0) { mutex_exit(&smcg->rlist_lock); delay(drv_usectohz(100000)); if (--i == 0) { cmn_err(CE_WARN, SMCG_NAME "%d: %d buffers not reclaimed", macinfo->gldm_ppa, smcg->rx_bufs_outstanding); return (DDI_FAILURE); } mutex_enter(&smcg->rlist_lock); } smcg->detaching_flag = 1; mutex_exit(&smcg->rlist_lock); /* * Unregister ourselves from the GLD interface * * gld_unregister will: * remove the minor node; * unlink us from the GLD system. */ if (gld_unregister(macinfo) != DDI_SUCCESS) { mutex_enter(&smcg->rlist_lock); smcg->detaching_flag = 0; mutex_exit(&smcg->rlist_lock); return (DDI_FAILURE); } ddi_remove_intr(devinfo, 0, macinfo->gldm_cookie); SMCG_dma_unalloc(smcg); mutex_destroy(&smcg->rbuf_lock); mutex_destroy(&smcg->txbuf_lock); mutex_destroy(&smcg->lm_lock); mutex_destroy(&smcg->rlist_lock); kmem_free(pAd, sizeof (Adapter_Struc)); kmem_free(smcg, sizeof (smcg_t)); gld_mac_free(macinfo); return (DDI_SUCCESS); }
/* * 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); }
/* * heci_remove - Device Removal Routine * * @pdev: PCI device information struct * * heci_remove is called by the PCI subsystem to alert the driver * that it should release a PCI device. */ static int heci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { struct iamt_heci_device *dev; int err; dev = ddi_get_soft_state(heci_soft_state_p, ddi_get_instance(dip)); ASSERT(dev != NULL); switch (cmd) { case DDI_SUSPEND: err = heci_suspend(dip); if (err) return (DDI_FAILURE); else return (DDI_SUCCESS); case DDI_DETACH: break; default: return (DDI_FAILURE); } if (dev->wd_timer) (void) untimeout(dev->wd_timer); mutex_enter(&dev->device_lock); if (dev->wd_file_ext.state == HECI_FILE_CONNECTED && dev->wd_timeout) { dev->wd_timeout = 0; dev->wd_due_counter = 0; (void) memcpy(dev->wd_data, stop_wd_params, HECI_WD_PARAMS_SIZE); dev->stop = 1; if (dev->host_buffer_is_empty && flow_ctrl_creds(dev, &dev->wd_file_ext)) { dev->host_buffer_is_empty = 0; if (!heci_send_wd(dev)) { DBG("send stop WD failed\n"); } else flow_ctrl_reduce(dev, &dev->wd_file_ext); dev->wd_pending = 0; } else dev->wd_pending = 1; dev->wd_stoped = 0; err = 0; while (!dev->wd_stoped && err != -1) { err = cv_reltimedwait(&dev->wait_stop_wd, &dev->device_lock, 10*HZ, TR_CLOCK_TICK); } if (!dev->wd_stoped) { DBG("stop wd failed to complete.\n"); } else { DBG("stop wd complete.\n"); } } mutex_exit(&dev->device_lock); if (dev->iamthif_file_ext.state == HECI_FILE_CONNECTED) { dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTING; (void) heci_disconnect_host_client(dev, &dev->iamthif_file_ext); } if (dev->wd_file_ext.state == HECI_FILE_CONNECTED) { dev->wd_file_ext.state = HECI_FILE_DISCONNECTING; (void) heci_disconnect_host_client(dev, &dev->wd_file_ext); } /* remove entry if already in list */ DBG("list del iamthif and wd file list.\n"); heci_remove_client_from_file_list(dev, dev->wd_file_ext. host_client_id); heci_remove_client_from_file_list(dev, dev->iamthif_file_ext.host_client_id); dev->iamthif_current_cb = NULL; dev->iamthif_file_ext.file = NULL; /* disable interrupts */ heci_csr_disable_interrupts(dev); ddi_remove_intr(dip, 0, dev->sc_iblk); if (dev->work) ddi_taskq_destroy(dev->work); if (dev->reinit_tsk) ddi_taskq_destroy(dev->reinit_tsk); if (dev->mem_addr) ddi_regs_map_free(&dev->io_handle); if (dev->me_clients && dev->num_heci_me_clients > 0) { kmem_free(dev->me_clients, sizeof (struct heci_me_client) * dev->num_heci_me_clients); } dev->num_heci_me_clients = 0; heci_destroy_locks(dev); ddi_remove_minor_node(dip, NULL); ddi_soft_state_free(heci_soft_state_p, ddi_get_instance(dip)); return (DDI_SUCCESS); }
/* * 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); }