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