~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/pci/syscall.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      pci_syscall.c
  3  *
  4  * For architectures where we want to allow direct access
  5  * to the PCI config stuff - it would probably be preferable
  6  * on PCs too, but there people just do it by hand with the
  7  * magic northbridge registers..
  8  */
  9 
 10 #include <linux/sched.h>
 11 #include <linux/errno.h>
 12 #include <linux/pci.h>
 13 #include <linux/smp_lock.h>
 14 #include <asm/uaccess.h>
 15 
 16 
 17 asmlinkage long
 18 sys_pciconfig_read(unsigned long bus, unsigned long dfn,
 19                    unsigned long off, unsigned long len, void *buf)
 20 {
 21         struct pci_dev *dev;
 22         u8 byte;
 23         u16 word;
 24         u32 dword;
 25         long err, cfg_ret;
 26 
 27         err = -EPERM;
 28         if (!capable(CAP_SYS_ADMIN))
 29                 goto error;
 30 
 31         err = -ENODEV;
 32         dev = pci_find_slot(bus, dfn);
 33         if (!dev)
 34                 goto error;
 35 
 36         lock_kernel();
 37         switch (len) {
 38         case 1:
 39                 cfg_ret = pci_read_config_byte(dev, off, &byte);
 40                 break;
 41         case 2:
 42                 cfg_ret = pci_read_config_word(dev, off, &word);
 43                 break;
 44         case 4:
 45                 cfg_ret = pci_read_config_dword(dev, off, &dword);
 46                 break;
 47         default:
 48                 err = -EINVAL;
 49                 unlock_kernel();
 50                 goto error;
 51         };
 52         unlock_kernel();
 53 
 54         err = -EIO;
 55         if (cfg_ret != PCIBIOS_SUCCESSFUL)
 56                 goto error;
 57 
 58         switch (len) {
 59         case 1:
 60                 err = put_user(byte, (unsigned char *)buf);
 61                 break;
 62         case 2:
 63                 err = put_user(word, (unsigned short *)buf);
 64                 break;
 65         case 4:
 66                 err = put_user(dword, (unsigned int *)buf);
 67                 break;
 68         };
 69         return err;
 70 
 71 error:
 72         /* ??? XFree86 doesn't even check the return value.  They
 73            just look for 0xffffffff in the output, since that's what
 74            they get instead of a machine check on x86.  */
 75         switch (len) {
 76         case 1:
 77                 put_user(-1, (unsigned char *)buf);
 78                 break;
 79         case 2:
 80                 put_user(-1, (unsigned short *)buf);
 81                 break;
 82         case 4:
 83                 put_user(-1, (unsigned int *)buf);
 84                 break;
 85         };
 86         return err;
 87 }
 88 
 89 asmlinkage long
 90 sys_pciconfig_write(unsigned long bus, unsigned long dfn,
 91                     unsigned long off, unsigned long len, void *buf)
 92 {
 93         struct pci_dev *dev;
 94         u8 byte;
 95         u16 word;
 96         u32 dword;
 97         int err = 0;
 98 
 99         if (!capable(CAP_SYS_ADMIN))
100                 return -EPERM;
101         if (!pcibios_present())
102                 return -ENOSYS;
103 
104         dev = pci_find_slot(bus, dfn);
105         if (!dev)
106                 return -ENODEV;
107 
108         lock_kernel();
109         switch(len) {
110         case 1:
111                 err = get_user(byte, (u8 *)buf);
112                 if (err)
113                         break;
114                 err = pci_write_config_byte(dev, off, byte);
115                 if (err != PCIBIOS_SUCCESSFUL)
116                         err = -EIO;
117                 break;
118 
119         case 2:
120                 err = get_user(word, (u16 *)buf);
121                 if (err)
122                         break;
123                 err = pci_write_config_word(dev, off, word);
124                 if (err != PCIBIOS_SUCCESSFUL)
125                         err = -EIO;
126                 break;
127 
128         case 4:
129                 err = get_user(dword, (u32 *)buf);
130                 if (err)
131                         break;
132                 err = pci_write_config_dword(dev, off, dword);
133                 if (err != PCIBIOS_SUCCESSFUL)
134                         err = -EIO;
135                 break;
136 
137         default:
138                 err = -EINVAL;
139                 break;
140         };
141         unlock_kernel();
142 
143         return err;
144 }
145 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.