/* * Halt driver processing * * This will be called just prior to unloading the module from memory. * Everything we've setup since we've been loaded must be undone here. * * Arguments: * none * * Returns: * 0 shutdown was successful * errno shutdown failed - reason indicated * */ static int fore_stop() { int err = 0; int s = splimp(); int i; /* * Stop the watchdog timer */ (void) atm_untimeout(&fore_timer); /* * Clean up each device (if any) */ for ( i = 0; i < fore_nunits; i++ ) { Fore_unit *fup = fore_units[i]; if (fup == NULL) continue; /* * Deregister device from kernel services */ if (err = atm_physif_deregister((Cmn_unit *)fup)) { (void) splx(s); return (err); } /* * Unattach the device from the system */ fore_unattach(fup); /* * Free any Fore-specific device resources */ fore_interface_free(fup); /* * Free the unit structure */ atm_dev_free(fup); fore_units[i] = NULL; } fore_nunits = 0; /* * Now free our global resources */ /* * Release our storage pools */ atm_release_pool(&fore_vcc_pool); atm_release_pool(&fore_nif_pool); /* * Release all DMA mappings */ DMA_RELEASE(); fore_inited = 0; (void) splx(s); return (0); }
/* * Begin CP Initialization * * This function will poll for the successful downloading and starting of * the CP microcode program. After the microcode is running, we will allocate * any needed kernel memory (must do it in non-interrupt mode), build the CP * queue configurations and issue an Initialize command to the CP. * * Arguments: * fup pointer to device unit structure * * Returns: * none */ void fore_initialize(void *xfup) { Fore_unit *fup = xfup; Aali *aap; Init_parms *inp; caddr_t errmsg; u_long vers; /* * Must wait until firmware has been downloaded and is running */ if (CP_READ(fup->fu_mon->mon_bstat) != BOOT_RUNNING) { /* * Try again later */ callout_reset(&fup->fu_init_timer, hz, fore_initialize, fup); return; } /* * Allocate queues and whatever else is needed */ if (fore_xmit_allocate(fup)) { errmsg = "transmit queue allocation"; goto failed; } if (fore_recv_allocate(fup)) { errmsg = "receive queue allocation"; goto failed; } if (fore_buf_allocate(fup)) { errmsg = "buffer supply queue allocation"; goto failed; } if (fore_cmd_allocate(fup)) { errmsg = "command queue allocation"; goto failed; } /* * CP microcode is downloaded - locate shared memory interface */ aap = (Aali *)(fup->fu_ram + CP_READ(fup->fu_mon->mon_appl)); fup->fu_aali = aap; /* * Pick out any interesting info from the microcode */ vers = CP_READ(aap->aali_ucode_ver); if (vers < FORE_MIN_UCODE) { errmsg = "unsupported microcode version"; goto failed; } ksnprintf(fup->fu_config.ac_firm_vers, sizeof(fup->fu_config.ac_firm_vers), "%ld.%ld.%ld", (vers >> 16) & 0xff, (vers >> 8) & 0xff, vers & 0xff); #ifdef notdef /* * Turn on CP debugging */ aap->aali_hostlog = 1; #endif /* * Build the initialization block */ inp = &aap->aali_init; inp->init_numvcc = CP_WRITE(FORE_MAX_VCC); inp->init_cmd_elem = CP_WRITE(CMD_QUELEN); inp->init_xmit_elem = CP_WRITE(XMIT_QUELEN); inp->init_recv_elem = CP_WRITE(RECV_QUELEN); inp->init_recv_ext = CP_WRITE(RECV_EXTRA_SEGS); inp->init_xmit_ext = CP_WRITE(XMIT_EXTRA_SEGS); inp->init_buf1s.bfs_quelen = CP_WRITE(BUF1_SM_QUELEN); inp->init_buf1s.bfs_bufsize = CP_WRITE(BUF1_SM_SIZE); inp->init_buf1s.bfs_cppool = CP_WRITE(BUF1_SM_CPPOOL); inp->init_buf1s.bfs_entsize = CP_WRITE(BUF1_SM_ENTSIZE); inp->init_buf1l.bfs_quelen = CP_WRITE(BUF1_LG_QUELEN); inp->init_buf1l.bfs_bufsize = CP_WRITE(BUF1_LG_SIZE); inp->init_buf1l.bfs_cppool = CP_WRITE(BUF1_LG_CPPOOL); inp->init_buf1l.bfs_entsize = CP_WRITE(BUF1_LG_ENTSIZE); inp->init_buf2s.bfs_quelen = CP_WRITE(0); inp->init_buf2s.bfs_bufsize = CP_WRITE(0); inp->init_buf2s.bfs_cppool = CP_WRITE(0); inp->init_buf2s.bfs_entsize = CP_WRITE(0); inp->init_buf2l.bfs_quelen = CP_WRITE(0); inp->init_buf2l.bfs_bufsize = CP_WRITE(0); inp->init_buf2l.bfs_cppool = CP_WRITE(0); inp->init_buf2l.bfs_entsize = CP_WRITE(0); /* * Enable device interrupts */ aap->aali_intr_ena = CP_WRITE(1); /* * Issue the Initialize command to the CP and wait for * the CP to interrupt to signal completion */ inp->init_status = CP_WRITE(QSTAT_PENDING); inp->init_cmd = CP_WRITE(CMD_INIT | CMD_INTR_REQ); return; failed: /* * Initialization failure */ fore_interface_free(fup); log(LOG_ERR, "fore initialization failed: intf=%s%d, err=%s\n", fup->fu_pif.pif_name, fup->fu_pif.pif_unit, errmsg); return; }