static status_t std_ops(int32 op, ...) { switch(op) { case B_MODULE_INIT: #if DEBUG_SAFETY set_dprintf_enabled(true); #endif load_driver_symbols("53c8xx"); if (get_module(pci_name, (module_info **) &pci) != B_OK) return B_ERROR; if (get_module(cam_name, (module_info **) &cam) != B_OK) { put_module(pci_name); return B_ERROR; } if(sim_install_symbios()){ return B_OK; } put_module(pci_name); put_module(cam_name); return B_ERROR; case B_MODULE_UNINIT: put_module(pci_name); put_module(cam_name); return B_OK; default: return B_ERROR; } }
status_t init_driver(void) { struct pci_info *item; int index; int cards; #if defined(DEBUG) && !defined(__HAIKU__) set_dprintf_enabled(true); load_driver_symbols("cx23882"); #endif dprintf(INFO); item = (pci_info *)malloc(sizeof(pci_info)); if (!item) return B_NO_MEMORY; if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK) { free(item); return B_ERROR; } for (cards = 0, index = 0; gPci->get_nth_pci_info(index++, item) == B_OK; ) { const char *info = identify_device(sCardTable, item); if (info) { char name[64]; sprintf(name, "dvb/cx23882/%d", cards + 1); dprintf("cx23882: /dev/%s is a %s\n", name, info); sDevList[cards] = item; sDevNameList[cards] = strdup(name); sDevNameList[cards + 1] = NULL; cards++; item = (pci_info *)malloc(sizeof(pci_info)); if (!item) goto err_outofmem; if (cards == MAX_CARDS) break; } } free(item); if (!cards) goto err_cards; return B_OK; err_outofmem: TRACE("cx23882: err_outofmem\n"); for (index = 0; index < cards; index++) { free(sDevList[index]); free(sDevNameList[index]); } err_cards: put_module(B_PCI_MODULE_NAME); return B_ERROR; }
extern "C" int _start(kernel_args *bootKernelArgs, int currentCPU) { if (bootKernelArgs->kernel_args_size != sizeof(kernel_args) || bootKernelArgs->version != CURRENT_KERNEL_ARGS_VERSION) { // This is something we cannot handle right now - release kernels // should always be able to handle the kernel_args of earlier // released kernels. debug_early_boot_message("Version mismatch between boot loader and " "kernel!\n"); return -1; } smp_set_num_cpus(bootKernelArgs->num_cpus); // wait for all the cpus to get here smp_cpu_rendezvous(&sCpuRendezvous, currentCPU); // the passed in kernel args are in a non-allocated range of memory if (currentCPU == 0) memcpy(&sKernelArgs, bootKernelArgs, sizeof(kernel_args)); smp_cpu_rendezvous(&sCpuRendezvous2, currentCPU); // do any pre-booting cpu config cpu_preboot_init_percpu(&sKernelArgs, currentCPU); thread_preboot_init_percpu(&sKernelArgs, currentCPU); // if we're not a boot cpu, spin here until someone wakes us up if (smp_trap_non_boot_cpus(currentCPU, &sCpuRendezvous3)) { // init platform arch_platform_init(&sKernelArgs); // setup debug output debug_init(&sKernelArgs); set_dprintf_enabled(true); dprintf("Welcome to kernel debugger output!\n"); dprintf("Haiku revision: %lu\n", get_haiku_revision()); // init modules TRACE("init CPU\n"); cpu_init(&sKernelArgs); cpu_init_percpu(&sKernelArgs, currentCPU); TRACE("init interrupts\n"); int_init(&sKernelArgs); TRACE("init VM\n"); vm_init(&sKernelArgs); // Before vm_init_post_sem() is called, we have to make sure that // the boot loader allocated region is not used anymore boot_item_init(); debug_init_post_vm(&sKernelArgs); low_resource_manager_init(); // now we can use the heap and create areas arch_platform_init_post_vm(&sKernelArgs); lock_debug_init(); TRACE("init driver_settings\n"); driver_settings_init(&sKernelArgs); debug_init_post_settings(&sKernelArgs); TRACE("init notification services\n"); notifications_init(); TRACE("init teams\n"); team_init(&sKernelArgs); TRACE("init ELF loader\n"); elf_init(&sKernelArgs); TRACE("init modules\n"); module_init(&sKernelArgs); TRACE("init semaphores\n"); haiku_sem_init(&sKernelArgs); TRACE("init interrupts post vm\n"); int_init_post_vm(&sKernelArgs); cpu_init_post_vm(&sKernelArgs); commpage_init(); TRACE("init system info\n"); system_info_init(&sKernelArgs); TRACE("init SMP\n"); smp_init(&sKernelArgs); TRACE("init timer\n"); timer_init(&sKernelArgs); TRACE("init real time clock\n"); rtc_init(&sKernelArgs); TRACE("init condition variables\n"); condition_variable_init(); // now we can create and use semaphores TRACE("init VM semaphores\n"); vm_init_post_sem(&sKernelArgs); TRACE("init generic syscall\n"); generic_syscall_init(); smp_init_post_generic_syscalls(); TRACE("init scheduler\n"); scheduler_init(); TRACE("init threads\n"); thread_init(&sKernelArgs); TRACE("init kernel daemons\n"); kernel_daemon_init(); arch_platform_init_post_thread(&sKernelArgs); TRACE("init I/O interrupts\n"); int_init_io(&sKernelArgs); TRACE("init VM threads\n"); vm_init_post_thread(&sKernelArgs); low_resource_manager_init_post_thread(); TRACE("init VFS\n"); vfs_init(&sKernelArgs); #if ENABLE_SWAP_SUPPORT TRACE("init swap support\n"); swap_init(); #endif TRACE("init POSIX semaphores\n"); realtime_sem_init(); xsi_sem_init(); xsi_msg_init(); // Start a thread to finish initializing the rest of the system. Note, // it won't be scheduled before calling scheduler_start() (on any CPU). TRACE("spawning main2 thread\n"); thread_id thread = spawn_kernel_thread(&main2, "main2", B_NORMAL_PRIORITY, NULL); resume_thread(thread); // We're ready to start the scheduler and enable interrupts on all CPUs. scheduler_enable_scheduling(); // bring up the AP cpus in a lock step fashion TRACE("waking up AP cpus\n"); sCpuRendezvous = sCpuRendezvous2 = 0; smp_wake_up_non_boot_cpus(); smp_cpu_rendezvous(&sCpuRendezvous, 0); // wait until they're booted // exit the kernel startup phase (mutexes, etc work from now on out) TRACE("exiting kernel startup\n"); gKernelStartup = false; smp_cpu_rendezvous(&sCpuRendezvous2, 0); // release the AP cpus to go enter the scheduler TRACE("starting scheduler on cpu 0 and enabling interrupts\n"); scheduler_start(); enable_interrupts(); } else { // lets make sure we're in sync with the main cpu // the boot processor has probably been sending us // tlb sync messages all along the way, but we've // been ignoring them arch_cpu_global_TLB_invalidate(); // this is run for each non boot processor after they've been set loose cpu_init_percpu(&sKernelArgs, currentCPU); smp_per_cpu_init(&sKernelArgs, currentCPU); // wait for all other AP cpus to get to this point smp_cpu_rendezvous(&sCpuRendezvous, currentCPU); smp_cpu_rendezvous(&sCpuRendezvous2, currentCPU); // welcome to the machine scheduler_start(); enable_interrupts(); } #ifdef TRACE_BOOT // We disable interrupts for this dprintf(), since otherwise dprintf() // would acquires a mutex, which is something we must not do in an idle // thread, or otherwise the scheduler would be seriously unhappy. disable_interrupts(); TRACE("main: done... begin idle loop on cpu %d\n", currentCPU); enable_interrupts(); #endif for (;;) arch_cpu_idle(); return 0; }
status_t init_driver(void) { struct pci_info *item; int index; int cards; #ifdef DEBUG set_dprintf_enabled(true); load_driver_symbols("ipro1000"); #endif dprintf("ipro1000: " INFO "\n"); item = (pci_info *)malloc(sizeof(pci_info)); if (!item) return B_NO_MEMORY; if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK) { free(item); return B_ERROR; } for (cards = 0, index = 0; gPci->get_nth_pci_info(index++, item) == B_OK; ) { const char *info = identify_device(item); if (info) { char name[64]; sprintf(name, "net/ipro1000/%d", cards); dprintf("ipro1000: /dev/%s is a %s\n", name, info); gDevList[cards] = item; gDevNameList[cards] = strdup(name); gDevNameList[cards + 1] = NULL; cards++; item = (pci_info *)malloc(sizeof(pci_info)); if (!item) goto err_outofmem; if (cards == MAX_CARDS) break; } } free(item); if (!cards) goto err_cards; if (initialize_timer() != B_OK) { ERROROUT("timer init failed"); goto err_timer; } if (mempool_init(cards * 768) != B_OK) { ERROROUT("mempool init failed"); goto err_mempool; } return B_OK; err_mempool: terminate_timer(); err_timer: err_cards: err_outofmem: for (index = 0; index < cards; index++) { free(gDevList[index]); free(gDevNameList[index]); } put_module(B_PCI_MODULE_NAME); return B_ERROR; }
static int32 bus_std_ops(int32 op, ...) { switch (op) { case B_MODULE_INIT: { TRACE_MODULE("init\n"); if (gUSBStack) return B_OK; #ifdef HAIKU_TARGET_PLATFORM_BEOS // This code is to handle plain R5 (non-BONE) where the same module // gets loaded multiple times (once for each exported module // interface, the USB v2 and v3 API in our case). We don't want to // ever create multiple stacks however, so we "share" the same stack // for both modules by storing it's address in a shared area. void *address = NULL; area_id shared = find_area("shared usb stack"); if (shared >= B_OK && clone_area("usb stack clone", &address, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, shared) >= B_OK) { gUSBStack = *((Stack **)address); TRACE_MODULE("found shared stack at %p\n", gUSBStack); return B_OK; } #endif #ifdef TRACE_USB set_dprintf_enabled(true); #ifndef HAIKU_TARGET_PLATFORM_HAIKU load_driver_symbols("usb"); #endif #endif Stack *stack = new(std::nothrow) Stack(); TRACE_MODULE("usb_module: stack created %p\n", stack); if (!stack) return B_NO_MEMORY; if (stack->InitCheck() != B_OK) { delete stack; return ENODEV; } gUSBStack = stack; #ifdef HAIKU_TARGET_PLATFORM_HAIKU add_debugger_command("get_usb_pipe_for_id", &debug_get_pipe_for_id, "Gets the config for a USB pipe"); #elif HAIKU_TARGET_PLATFORM_BEOS // Plain R5 workaround, see comment above. shared = create_area("shared usb stack", &address, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_KERNEL_WRITE_AREA); if (shared >= B_OK) *((Stack **)address) = gUSBStack; #endif break; } case B_MODULE_UNINIT: TRACE_MODULE("uninit\n"); delete gUSBStack; gUSBStack = NULL; #ifdef HAIKU_TARGET_PLATFORM_HAIKU remove_debugger_command("get_usb_pipe_for_id", &debug_get_pipe_for_id); #endif break; default: return EINVAL; } return B_OK; }
status_t OHCI::AddTo(Stack *stack) { #ifdef TRACE_USB set_dprintf_enabled(true); #ifndef ANTARES_TARGET_PLATFORM_ANTARES load_driver_symbols("ohci"); #endif #endif if (!sPCIModule) { status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); if (status < B_OK) { TRACE_MODULE_ERROR("getting pci module failed! 0x%08lx\n", status); return status; } } TRACE_MODULE("searching devices\n"); bool found = false; pci_info *item = new(std::nothrow) pci_info; if (!item) { sPCIModule = NULL; put_module(B_PCI_MODULE_NAME); return B_NO_MEMORY; } for (uint32 i = 0 ; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) { if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb && item->class_api == PCI_usb_ohci) { if (item->u.h0.interrupt_line == 0 || item->u.h0.interrupt_line == 0xFF) { TRACE_MODULE_ERROR("found device with invalid IRQ -" " check IRQ assignement\n"); continue; } TRACE_MODULE("found device at IRQ %u\n", item->u.h0.interrupt_line); OHCI *bus = new(std::nothrow) OHCI(item, stack); if (!bus) { delete item; sPCIModule = NULL; put_module(B_PCI_MODULE_NAME); return B_NO_MEMORY; } if (bus->InitCheck() < B_OK) { TRACE_MODULE_ERROR("bus failed init check\n"); delete bus; continue; } // the bus took it away item = new(std::nothrow) pci_info; bus->Start(); stack->AddBusManager(bus); found = true; } } if (!found) { TRACE_MODULE_ERROR("no devices found\n"); delete item; sPCIModule = NULL; put_module(B_PCI_MODULE_NAME); return ENODEV; } delete item; return B_OK; }