home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / arch / i386 / kernel / ioport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-11  |  2.1 KB  |  90 lines

  1. /*
  2.  *    linux/arch/i386/kernel/ioport.c
  3.  *
  4.  * This contains the io-permission bitmap code - written by obz, with changes
  5.  * by Linus.
  6.  */
  7.  
  8. #include <linux/sched.h>
  9. #include <linux/kernel.h>
  10. #include <linux/errno.h>
  11. #include <linux/types.h>
  12. #include <linux/ioport.h>
  13.  
  14. /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
  15. static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
  16. {
  17.     int mask;
  18.     unsigned long *bitmap_base = bitmap + (base >> 5);
  19.     unsigned short low_index = base & 0x1f;
  20.     int length = low_index + extent;
  21.  
  22.     if (low_index != 0) {
  23.         mask = (~0 << low_index);
  24.         if (length < 32)
  25.                 mask &= ~(~0 << length);
  26.         if (new_value)
  27.             *bitmap_base++ |= mask;
  28.         else
  29.             *bitmap_base++ &= ~mask;
  30.         length -= 32;
  31.     }
  32.  
  33.     mask = (new_value ? ~0 : 0);
  34.     while (length >= 32) {
  35.         *bitmap_base++ = mask;
  36.         length -= 32;
  37.     }
  38.  
  39.     if (length > 0) {
  40.         mask = ~(~0 << length);
  41.         if (new_value)
  42.             *bitmap_base++ |= mask;
  43.         else
  44.             *bitmap_base++ &= ~mask;
  45.     }
  46. }
  47.  
  48. /*
  49.  * this changes the io permissions bitmap in the current task.
  50.  */
  51. asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
  52. {
  53.     if (from + num <= from)
  54.         return -EINVAL;
  55.     if (from + num > IO_BITMAP_SIZE*32)
  56.         return -EINVAL;
  57.     if (!suser())
  58.         return -EPERM;
  59.  
  60.     set_bitmap((unsigned long *)current->tss.io_bitmap, from, num, !turn_on);
  61.     return 0;
  62. }
  63.  
  64. unsigned int *stack;
  65.  
  66. /*
  67.  * sys_iopl has to be used when you want to access the IO ports
  68.  * beyond the 0x3ff range: to get the full 65536 ports bitmapped
  69.  * you'd need 8kB of bitmaps/process, which is a bit excessive.
  70.  *
  71.  * Here we just change the eflags value on the stack: we allow
  72.  * only the super-user to do it. This depends on the stack-layout
  73.  * on system-call entry - see also fork() and the signal handling
  74.  * code.
  75.  */
  76. asmlinkage int sys_iopl(long ebx,long ecx,long edx,
  77.          long esi, long edi, long ebp, long eax, long ds,
  78.          long es, long fs, long gs, long orig_eax,
  79.          long eip,long cs,long eflags,long esp,long ss)
  80. {
  81.     unsigned int level = ebx;
  82.  
  83.     if (level > 3)
  84.         return -EINVAL;
  85.     if (!suser())
  86.         return -EPERM;
  87.     *(&eflags) = (eflags & 0xffffcfff) | (level << 12);
  88.     return 0;
  89. }
  90.