OsdSchedule.c revision 71418
167760Smsmith/*- 267760Smsmith * Copyright (c) 2000 Michael Smith 367760Smsmith * Copyright (c) 2000 BSDi 467760Smsmith * All rights reserved. 567760Smsmith * 667760Smsmith * Redistribution and use in source and binary forms, with or without 767760Smsmith * modification, are permitted provided that the following conditions 867760Smsmith * are met: 967760Smsmith * 1. Redistributions of source code must retain the above copyright 1067760Smsmith * notice, this list of conditions and the following disclaimer. 1167760Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1267760Smsmith * notice, this list of conditions and the following disclaimer in the 1367760Smsmith * documentation and/or other materials provided with the distribution. 1467760Smsmith * 1567760Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1667760Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1767760Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1867760Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1967760Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2067760Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2167760Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2267760Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2367760Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2467760Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2567760Smsmith * SUCH DAMAGE. 2667760Smsmith * 2767760Smsmith * $FreeBSD: head/sys/dev/acpica/Osd/OsdSchedule.c 71418 2001-01-23 09:43:23Z peter $ 2867760Smsmith */ 2967760Smsmith 3067760Smsmith/* 3167760Smsmith * 6.3 : Scheduling services 3267760Smsmith */ 3367760Smsmith 3467760Smsmith#include "acpi.h" 3567760Smsmith 3667760Smsmith#include <sys/kernel.h> 3767760Smsmith#include <sys/malloc.h> 3867760Smsmith#include <sys/taskqueue.h> 3967760Smsmith#include <machine/clock.h> 4067760Smsmith 4167760Smsmith/* 4267760Smsmith * This is a little complicated due to the fact that we need to build and then 4367760Smsmith * free a 'struct task' for each task we enqueue. 4467760Smsmith * 4567760Smsmith * We use the default taskqueue_swi queue, since it really doesn't matter what 4667760Smsmith * else we're queued along with. 4767760Smsmith */ 4867760Smsmith 4967760SmsmithMALLOC_DEFINE(M_ACPITASK, "acpitask", "ACPI deferred task"); 5067760Smsmith 5167760Smsmithstatic void AcpiOsExecuteQueue(void *arg, int pending); 5267760Smsmith 5367760Smsmithstruct acpi_task { 5467760Smsmith struct task at_task; 5567760Smsmith OSD_EXECUTION_CALLBACK at_function; 5667760Smsmith void *at_context; 5767760Smsmith}; 5867760Smsmith 5967760SmsmithACPI_STATUS 6067760SmsmithAcpiOsQueueForExecution(UINT32 Priority, OSD_EXECUTION_CALLBACK Function, void *Context) 6167760Smsmith{ 6267760Smsmith struct acpi_task *at; 6367760Smsmith 6467760Smsmith if (Function == NULL) 6567760Smsmith return(AE_BAD_PARAMETER); 6667760Smsmith 6771418Speter at = malloc(sizeof(*at), M_ACPITASK, M_NOWAIT); /* Interrupt Context */ 6871418Speter if (at == NULL) 6971418Speter return(AE_NO_MEMORY); 7067760Smsmith bzero(at, sizeof(*at)); 7167760Smsmith 7267760Smsmith at->at_function = Function; 7367760Smsmith at->at_context = Context; 7467760Smsmith at->at_task.ta_func = AcpiOsExecuteQueue; 7567760Smsmith at->at_task.ta_context = at; 7667760Smsmith switch (Priority) { 7770236Siwasaki case OSD_PRIORITY_GPE: 7870236Siwasaki at->at_task.ta_priority = 4; 7970236Siwasaki break; 8067760Smsmith case OSD_PRIORITY_HIGH: 8167760Smsmith at->at_task.ta_priority = 3; 8267760Smsmith break; 8367760Smsmith case OSD_PRIORITY_MED: 8467760Smsmith at->at_task.ta_priority = 2; 8567760Smsmith break; 8667760Smsmith case OSD_PRIORITY_LO: 8767760Smsmith at->at_task.ta_priority = 1; 8867760Smsmith break; 8967760Smsmith default: 9067760Smsmith free(at, M_ACPITASK); 9167760Smsmith return(AE_BAD_PARAMETER); 9267760Smsmith } 9367760Smsmith 9467760Smsmith taskqueue_enqueue(taskqueue_swi, (struct task *)at); 9567760Smsmith return(AE_OK); 9667760Smsmith} 9767760Smsmith 9867760Smsmithstatic void 9967760SmsmithAcpiOsExecuteQueue(void *arg, int pending) 10067760Smsmith{ 10167760Smsmith struct acpi_task *at = (struct acpi_task *)arg; 10267760Smsmith OSD_EXECUTION_CALLBACK Function; 10367760Smsmith void *Context; 10467760Smsmith 10567760Smsmith Function = (OSD_EXECUTION_CALLBACK)at->at_function; 10667760Smsmith Context = at->at_context; 10767760Smsmith 10867760Smsmith free(at, M_ACPITASK); 10967760Smsmith 11067760Smsmith Function(Context); 11167760Smsmith} 11267760Smsmith 11367760Smsmith/* 11467760Smsmith * We don't have any sleep granularity better than hz, so 11567760Smsmith * make do with that. 11667760Smsmith */ 11767760Smsmithvoid 11867760SmsmithAcpiOsSleep (UINT32 Seconds, UINT32 Milliseconds) 11967760Smsmith{ 12067760Smsmith int timo; 12167760Smsmith 12267760Smsmith timo = (Seconds * hz) + Milliseconds / (1000 * hz); 12367760Smsmith if (timo == 0) 12467760Smsmith timo = 1; 12567760Smsmith tsleep(NULL, 0, "acpislp", timo); 12667760Smsmith} 12767760Smsmith 12867760Smsmithvoid 12967760SmsmithAcpiOsSleepUsec (UINT32 Microseconds) 13067760Smsmith{ 13167760Smsmith if (Microseconds > 1000) { /* long enough to be worth the overhead of sleeping */ 13267760Smsmith AcpiOsSleep(0, Microseconds / 1000); 13367760Smsmith } else { 13467760Smsmith DELAY(Microseconds); 13567760Smsmith } 13667760Smsmith} 137