?? os.c
字號:
{ int devfn = PCI_DEVFN(pci_id->device, pci_id->function); struct pci_dev *dev = pci_find_slot(pci_id->bus, devfn); if (!value || !dev) return AE_ERROR; switch (width) { case 8: if (pci_read_config_byte(dev, reg, (u8*) value)) return AE_ERROR; break; case 16: if (pci_read_config_word(dev, reg, (u16*) value)) return AE_ERROR; break; case 32: if (pci_read_config_dword(dev, reg, (u32*) value)) return AE_ERROR; break; default: BUG(); } return AE_OK;}acpi_statusacpi_os_write_pci_configuration ( acpi_pci_id *pci_id, u32 reg, u32 value, u32 width){ int devfn = PCI_DEVFN(pci_id->device, pci_id->function); struct pci_dev *dev = pci_find_slot(pci_id->bus, devfn); if (!dev) return AE_ERROR; switch (width) { case 8: if (pci_write_config_byte(dev, reg, value)) return AE_ERROR; break; case 16: if (pci_write_config_word(dev, reg, value)) return AE_ERROR; break; case 32: if (pci_write_config_dword(dev, reg, value)) return AE_ERROR; break; default: BUG(); } return AE_OK;}#endif /*CONFIG_ACPI_PCI*/acpi_statusacpi_os_load_module ( char *module_name){ PROC_NAME("acpi_os_load_module"); if (!module_name) return AE_BAD_PARAMETER; if (0 > request_module(module_name)) { ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to load module [%s].\n", module_name)); return AE_ERROR; } return AE_OK;}acpi_statusacpi_os_unload_module ( char *module_name){ if (!module_name) return AE_BAD_PARAMETER; /* TODO: How on Linux? */ /* this is done automatically for all modules with use_count = 0, I think. see: MOD_INC_USE_COUNT -ASG */ return AE_OK;}/* * See acpi_os_queue_for_execution() */static intacpi_os_queue_exec ( void *context){ ACPI_OS_DPC *dpc = (ACPI_OS_DPC*)context; PROC_NAME("acpi_os_queue_exec"); daemonize(); strcpy(current->comm, "kacpidpc"); if (!dpc || !dpc->function) return AE_BAD_PARAMETER; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Executing function [%p(%p)].\n", dpc->function, dpc->context)); dpc->function(dpc->context); kfree(dpc); return 1;}static voidacpi_os_schedule_exec ( void *context){ ACPI_OS_DPC *dpc = NULL; int thread_pid = -1; PROC_NAME("acpi_os_schedule_exec"); dpc = (ACPI_OS_DPC*)context; if (!dpc) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); return; } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating new thread to run function [%p(%p)].\n", dpc->function, dpc->context)); thread_pid = kernel_thread(acpi_os_queue_exec, dpc, (CLONE_FS | CLONE_FILES | SIGCHLD)); if (thread_pid < 0) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to kernel_thread() failed.\n")); acpi_os_free(dpc); }}acpi_statusacpi_os_queue_for_execution( u32 priority, OSD_EXECUTION_CALLBACK function, void *context){ acpi_status status = AE_OK; ACPI_OS_DPC *dpc = NULL; PROC_NAME("acpi_os_queue_for_execution"); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Scheduling function [%p(%p)] for deferred execution.\n", function, context)); if (!function) return AE_BAD_PARAMETER; /* * Queue via DPC: * -------------- * Note that we have to use two different processes for queuing DPCs: * Interrupt-Level: Use schedule_task; can't spawn a new thread. * Kernel-Level: Spawn a new kernel thread, as schedule_task has * its limitations (e.g. single-threaded model), and * all other task queues run at interrupt-level. */ switch (priority) { case OSD_PRIORITY_GPE: { static struct tq_struct task; /* * Allocate/initialize DPC structure. Note that this memory will be * freed by the callee. */ dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_ATOMIC); if (!dpc) return AE_NO_MEMORY; dpc->function = function; dpc->context = context; memset(&task, 0, sizeof(struct tq_struct)); task.routine = acpi_os_schedule_exec; task.data = (void*)dpc; if (schedule_task(&task) < 0) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to schedule_task() failed.\n")); status = AE_ERROR; } } break; default: /* * Allocate/initialize DPC structure. Note that this memory will be * freed by the callee. */ dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_KERNEL); if (!dpc) return AE_NO_MEMORY; dpc->function = function; dpc->context = context; acpi_os_schedule_exec(dpc); break; } return status;}acpi_statusacpi_os_create_semaphore( u32 max_units, u32 initial_units, acpi_handle *handle){ struct semaphore *sem = NULL; PROC_NAME("acpi_os_create_semaphore"); sem = acpi_os_callocate(sizeof(struct semaphore)); if (!sem) return AE_NO_MEMORY; sema_init(sem, initial_units); *handle = (acpi_handle*)sem; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating semaphore[%p|%d].\n", *handle, initial_units)); return AE_OK;}/* * TODO: A better way to delete semaphores? Linux doesn't have a * 'delete_semaphore()' function -- may result in an invalid * pointer dereference for non-synchronized consumers. Should * we at least check for blocked threads and signal/cancel them? */acpi_statusacpi_os_delete_semaphore( acpi_handle handle){ struct semaphore *sem = (struct semaphore*) handle; PROC_NAME("acpi_os_delete_semaphore"); if (!sem) return AE_BAD_PARAMETER; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting semaphore[%p].\n", handle)); acpi_os_free(sem); sem = NULL; return AE_OK;}/* * TODO: The kernel doesn't have a 'down_timeout' function -- had to * improvise. The process is to sleep for one scheduler quantum * until the semaphore becomes available. Downside is that this * may result in starvation for timeout-based waits when there's * lots of semaphore activity. * * TODO: Support for units > 1? */acpi_statusacpi_os_wait_semaphore( acpi_handle handle, u32 units, u32 timeout){ acpi_status status = AE_OK; struct semaphore *sem = (struct semaphore*)handle; int ret = 0; PROC_NAME("acpi_os_wait_semaphore"); if (!sem || (units < 1)) return AE_BAD_PARAMETER; if (units > 1) return AE_SUPPORT; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout)); switch (timeout) { /* * No Wait: * -------- * A zero timeout value indicates that we shouldn't wait - just * acquire the semaphore if available otherwise return AE_TIME * (a.k.a. 'would block'). */ case 0: if(down_trylock(sem)) status = AE_TIME; break; /* * Wait Indefinitely: * ------------------ */ case WAIT_FOREVER: ret = down_interruptible(sem); if (ret < 0) status = AE_ERROR; break; /* * Wait w/ Timeout: * ---------------- */ default: // TODO: A better timeout algorithm? { int i = 0; static const int quantum_ms = 1000/HZ; ret = down_trylock(sem); for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); ret = down_trylock(sem); } if (ret != 0) status = AE_TIME; } break; } if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Failed to acquire semaphore[%p|%d|%d]\n", handle, units, timeout)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout)); } return status;}/* * TODO: Support for units > 1? */acpi_statusacpi_os_signal_semaphore( acpi_handle handle, u32 units){ struct semaphore *sem = (struct semaphore *) handle; PROC_NAME("acpi_os_signal_semaphore"); if (!sem || (units < 1)) return AE_BAD_PARAMETER; if (units > 1) return AE_SUPPORT; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Signaling semaphore[%p|%d]\n", handle, units)); up(sem); return AE_OK;}u32acpi_os_get_line(NATIVE_CHAR *buffer){#ifdef ENABLE_DEBUGGER if (acpi_in_debugger) { u32 chars; kdb_read(buffer, sizeof(line_buf)); /* remove the CR kdb includes */ chars = strlen(buffer) - 1; buffer[chars] = '\0'; }#endif return 0;}/* * We just have to assume we're dealing with valid memory */BOOLEANacpi_os_readable(void *ptr, u32 len){ return 1;}BOOLEANacpi_os_writable(void *ptr, u32 len){ return 1;}u32acpi_os_get_thread_id (void){ if (!in_interrupt()) return current->pid; return 0;}acpi_statusacpi_os_signal ( u32 function, void *info){ switch (function) { case ACPI_SIGNAL_FATAL: printk(KERN_ERR "ACPI: Fatal opcode executed\n"); break; case ACPI_SIGNAL_BREAKPOINT: { char *bp_info = (char*) info; printk(KERN_ERR "ACPI breakpoint: %s\n", bp_info); } default: break; } return AE_OK;}acpi_statusacpi_os_breakpoint(NATIVE_CHAR *msg){ acpi_os_printf("breakpoint: %s", msg); return AE_OK;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -