/* $XdotOrg$ */ /* * Copyright 2001 by Kean Johnston * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name Kean Johnston not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Kean Johnston makes no * representations about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. * * KEAN JOHNSTON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEAN JOHNSTON BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $XConsortium$ */ #include #include "compiler.h" #define _NEED_SYSI86 #include "xf86.h" #include "xf86Priv.h" #include "xf86OSpriv.h" #include "xf86_OSlib.h" /***************************************************************************/ /* I/O Permissions section */ /***************************************************************************/ /* * There is a right way and a wrong way of doing this. Unfortunately, we * are forced to do it the wrong way. The right way is to be told the range * or ranges of I/O ports the driver(s) need access to, in order to use the * CONS_IOPERM ioctl() to grant access only to those ports we care about. * This way we can guarantee some small level of stability because a driver * does not have access to all ports (which would mean it could play with * the PIT and thus affect scheduling times, or a whole slew of other * nasty things). However, because XFree86 currently only enables or disables * ALL port access, we need to run at IOPL 3, which basically means the * X Server runs at the same level as the kernel. You can image why this is * unsafe. Oh, and this is not a problem unique to OSR5, other OSes are * affected by this as well. * * So, for the time being, we change our IOPL until such time as the XFree86 * architecture is changed to allow for tighter control of I/O ports. If and * when it is, then the CONS_ADDIOP/DELIOP ioctl() should be used to enable * or disable access to the desired ports. */ extern long sysi86 (int cmd, ...); static Bool IOEnabled = FALSE; Bool xf86EnableIO(void) { if (IOEnabled) return TRUE; if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) { xf86Msg(X_WARNING,"Failed to set IOPL for extended I/O\n"); return FALSE; } IOEnabled = TRUE; return TRUE; } void xf86DisableIO(void) { if (!IOEnabled) return; sysi86(SI86V86, V86SC_IOPL, 0); IOEnabled = FALSE; } /***************************************************************************/ /* Interrupt Handling section */ /***************************************************************************/ Bool xf86DisableInterrupts() { if (!IOEnabled) { if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) return FALSE; } #ifdef __GNUC__ __asm__ __volatile__("cli"); #else asm("cli"); #endif /* __GNUC__ */ if (!IOEnabled) { sysi86(SI86V86, V86SC_IOPL, PS_IOPL); } return(TRUE); } void xf86EnableInterrupts() { if (!IOEnabled) { if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) return; } #ifdef __GNUC__ __asm__ __volatile__("sti"); #else asm("sti"); #endif /* __GNUC__ */ if (!IOEnabled) { sysi86(SI86V86, V86SC_IOPL, PS_IOPL); } }