1 /* 2 * Procfs interface for the PCI bus. 3 * 4 * Copyright (c) 1997--1999 Martin Mares <mj@ucw.cz> 5 */ 6 7 #include <linux/init.h> 8 #include <linux/pci.h> 9 #include <linux/slab.h> 10 #include <linux/module.h> 11 #include <linux/proc_fs.h> 12 #include <linux/seq_file.h> 13 #include <linux/capability.h> 14 #include <asm/uaccess.h> 15 #include <asm/byteorder.h> 16 #include "pci.h" 17 18 static int proc_initialized; /* = 0 */ 19 20 static loff_t 21 proc_bus_pci_lseek(struct file *file, loff_t off, int whence) 22 { 23 struct pci_dev *dev = PDE_DATA(file_inode(file)); 24 return fixed_size_llseek(file, off, whence, dev->cfg_size); 25 } 26 27 static ssize_t 28 proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) 29 { 30 struct pci_dev *dev = PDE_DATA(file_inode(file)); 31 unsigned int pos = *ppos; 32 unsigned int cnt, size; 33 34 /* 35 * Normal users can read only the standardized portion of the 36 * configuration space as several chips lock up when trying to read 37 * undefined locations (think of Intel PIIX4 as a typical example). 38 */ 39 40 if (capable(CAP_SYS_ADMIN)) 41 size = dev->cfg_size; 42 else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 43 size = 128; 44 else 45 size = 64; 46 47 if (pos >= size) 48 return 0; 49 if (nbytes >= size) 50 nbytes = size; 51 if (pos + nbytes > size) 52 nbytes = size - pos; 53 cnt = nbytes; 54 55 if (!access_ok(VERIFY_WRITE, buf, cnt)) 56 return -EINVAL; 57 58 pci_config_pm_runtime_get(dev); 59 60 if ((pos & 1) && cnt) { 61 unsigned char val; 62 pci_user_read_config_byte(dev, pos, &val); 63 __put_user(val, buf); 64 buf++; 65 pos++; 66 cnt--; 67 } 68 69 if ((pos & 3) && cnt > 2) { 70 unsigned short val; 71 pci_user_read_config_word(dev, pos, &val); 72 __put_user(cpu_to_le16(val), (__le16 __user *) buf); 73 buf += 2; 74 pos += 2; 75 cnt -= 2; 76 } 77 78 while (cnt >= 4) { 79 unsigned int val; 80 pci_user_read_config_dword(dev, pos, &val); 81 __put_user(cpu_to_le32(val), (__le32 __user *) buf); 82 buf += 4; 83 pos += 4; 84 cnt -= 4; 85 } 86 87 if (cnt >= 2) { 88 unsigned short val; 89 pci_user_read_config_word(dev, pos, &val); 90 __put_user(cpu_to_le16(val), (__le16 __user *) buf); 91 buf += 2; 92 pos += 2; 93 cnt -= 2; 94 } 95 96 if (cnt) { 97 unsigned char val; 98 pci_user_read_config_byte(dev, pos, &val); 99 __put_user(val, buf); 100 buf++; 101 pos++; 102 cnt--; 103 } 104 105 pci_config_pm_runtime_put(dev); 106 107 *ppos = pos; 108 return nbytes; 109 } 110 111 static ssize_t 112 proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos) 113 { 114 struct inode *ino = file_inode(file); 115 struct pci_dev *dev = PDE_DATA(ino); 116 int pos = *ppos; 117 int size = dev->cfg_size; 118 int cnt; 119 120 if (pos >= size) 121 return 0; 122 if (nbytes >= size) 123 nbytes = size; 124 if (pos + nbytes > size) 125 nbytes = size - pos; 126 cnt = nbytes; 127 128 if (!access_ok(VERIFY_READ, buf, cnt)) 129 return -EINVAL; 130 131 pci_config_pm_runtime_get(dev); 132 133 if ((pos & 1) && cnt) { 134 unsigned char val; 135 __get_user(val, buf); 136 pci_user_write_config_byte(dev, pos, val); 137 buf++; 138 pos++; 139 cnt--; 140 } 141 142 if ((pos & 3) && cnt > 2) { 143 __le16 val; 144 __get_user(val, (__le16 __user *) buf); 145 pci_user_write_config_word(dev, pos, le16_to_cpu(val)); 146 buf += 2; 147 pos += 2; 148 cnt -= 2; 149 } 150 151 while (cnt >= 4) { 152 __le32 val; 153 __get_user(val, (__le32 __user *) buf); 154 pci_user_write_config_dword(dev, pos, le32_to_cpu(val)); 155 buf += 4; 156 pos += 4; 157 cnt -= 4; 158 } 159 160 if (cnt >= 2) { 161 __le16 val; 162 __get_user(val, (__le16 __user *) buf); 163 pci_user_write_config_word(dev, pos, le16_to_cpu(val)); 164 buf += 2; 165 pos += 2; 166 cnt -= 2; 167 } 168 169 if (cnt) { 170 unsigned char val; 171 __get_user(val, buf); 172 pci_user_write_config_byte(dev, pos, val); 173 buf++; 174 pos++; 175 cnt--; 176 } 177 178 pci_config_pm_runtime_put(dev); 179 180 *ppos = pos; 181 i_size_write(ino, dev->cfg_size); 182 return nbytes; 183 } 184 185 struct pci_filp_private { 186 enum pci_mmap_state mmap_state; 187 int write_combine; 188 }; 189 190 static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, 191 unsigned long arg) 192 { 193 struct pci_dev *dev = PDE_DATA(file_inode(file)); 194 #ifdef HAVE_PCI_MMAP 195 struct pci_filp_private *fpriv = file->private_data; 196 #endif /* HAVE_PCI_MMAP */ 197 int ret = 0; 198 199 switch (cmd) { 200 case PCIIOC_CONTROLLER: 201 ret = pci_domain_nr(dev->bus); 202 break; 203 204 #ifdef HAVE_PCI_MMAP 205 case PCIIOC_MMAP_IS_IO: 206 fpriv->mmap_state = pci_mmap_io; 207 break; 208 209 case PCIIOC_MMAP_IS_MEM: 210 fpriv->mmap_state = pci_mmap_mem; 211 break; 212 213 case PCIIOC_WRITE_COMBINE: 214 if (arg) 215 fpriv->write_combine = 1; 216 else 217 fpriv->write_combine = 0; 218 break; 219 220 #endif /* HAVE_PCI_MMAP */ 221 222 default: 223 ret = -EINVAL; 224 break; 225 }; 226 227 return ret; 228 } 229 230 #ifdef HAVE_PCI_MMAP 231 static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) 232 { 233 struct pci_dev *dev = PDE_DATA(file_inode(file)); 234 struct pci_filp_private *fpriv = file->private_data; 235 int i, ret; 236 237 if (!capable(CAP_SYS_RAWIO)) 238 return -EPERM; 239 240 /* Make sure the caller is mapping a real resource for this device */ 241 for (i = 0; i < PCI_ROM_RESOURCE; i++) { 242 if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) 243 break; 244 } 245 246 if (i >= PCI_ROM_RESOURCE) 247 return -ENODEV; 248 249 ret = pci_mmap_page_range(dev, vma, 250 fpriv->mmap_state, 251 fpriv->write_combine); 252 if (ret < 0) 253 return ret; 254 255 return 0; 256 } 257 258 static int proc_bus_pci_open(struct inode *inode, struct file *file) 259 { 260 struct pci_filp_private *fpriv = kmalloc(sizeof(*fpriv), GFP_KERNEL); 261 262 if (!fpriv) 263 return -ENOMEM; 264 265 fpriv->mmap_state = pci_mmap_io; 266 fpriv->write_combine = 0; 267 268 file->private_data = fpriv; 269 270 return 0; 271 } 272 273 static int proc_bus_pci_release(struct inode *inode, struct file *file) 274 { 275 kfree(file->private_data); 276 file->private_data = NULL; 277 278 return 0; 279 } 280 #endif /* HAVE_PCI_MMAP */ 281 282 static const struct file_operations proc_bus_pci_operations = { 283 .owner = THIS_MODULE, 284 .llseek = proc_bus_pci_lseek, 285 .read = proc_bus_pci_read, 286 .write = proc_bus_pci_write, 287 .unlocked_ioctl = proc_bus_pci_ioctl, 288 .compat_ioctl = proc_bus_pci_ioctl, 289 #ifdef HAVE_PCI_MMAP 290 .open = proc_bus_pci_open, 291 .release = proc_bus_pci_release, 292 .mmap = proc_bus_pci_mmap, 293 #ifdef HAVE_ARCH_PCI_GET_UNMAPPED_AREA 294 .get_unmapped_area = get_pci_unmapped_area, 295 #endif /* HAVE_ARCH_PCI_GET_UNMAPPED_AREA */ 296 #endif /* HAVE_PCI_MMAP */ 297 }; 298 299 /* iterator */ 300 static void *pci_seq_start(struct seq_file *m, loff_t *pos) 301 { 302 struct pci_dev *dev = NULL; 303 loff_t n = *pos; 304 305 for_each_pci_dev(dev) { 306 if (!n--) 307 break; 308 } 309 return dev; 310 } 311 312 static void *pci_seq_next(struct seq_file *m, void *v, loff_t *pos) 313 { 314 struct pci_dev *dev = v; 315 316 (*pos)++; 317 dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); 318 return dev; 319 } 320 321 static void pci_seq_stop(struct seq_file *m, void *v) 322 { 323 if (v) { 324 struct pci_dev *dev = v; 325 pci_dev_put(dev); 326 } 327 } 328 329 static int show_device(struct seq_file *m, void *v) 330 { 331 const struct pci_dev *dev = v; 332 const struct pci_driver *drv; 333 int i; 334 335 if (dev == NULL) 336 return 0; 337 338 drv = pci_dev_driver(dev); 339 seq_printf(m, "%02x%02x\t%04x%04x\t%x", 340 dev->bus->number, 341 dev->devfn, 342 dev->vendor, 343 dev->device, 344 dev->irq); 345 346 /* only print standard and ROM resources to preserve compatibility */ 347 for (i = 0; i <= PCI_ROM_RESOURCE; i++) { 348 resource_size_t start, end; 349 pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); 350 seq_printf(m, "\t%16llx", 351 (unsigned long long)(start | 352 (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); 353 } 354 for (i = 0; i <= PCI_ROM_RESOURCE; i++) { 355 resource_size_t start, end; 356 pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); 357 seq_printf(m, "\t%16llx", 358 dev->resource[i].start < dev->resource[i].end ? 359 (unsigned long long)(end - start) + 1 : 0); 360 } 361 seq_putc(m, '\t'); 362 if (drv) 363 seq_printf(m, "%s", drv->name); 364 seq_putc(m, '\n'); 365 return 0; 366 } 367 368 static const struct seq_operations proc_bus_pci_devices_op = { 369 .start = pci_seq_start, 370 .next = pci_seq_next, 371 .stop = pci_seq_stop, 372 .show = show_device 373 }; 374 375 static struct proc_dir_entry *proc_bus_pci_dir; 376 377 int pci_proc_attach_device(struct pci_dev *dev) 378 { 379 struct pci_bus *bus = dev->bus; 380 struct proc_dir_entry *e; 381 char name[16]; 382 383 if (!proc_initialized) 384 return -EACCES; 385 386 if (!bus->procdir) { 387 if (pci_proc_domain(bus)) { 388 sprintf(name, "%04x:%02x", pci_domain_nr(bus), 389 bus->number); 390 } else { 391 sprintf(name, "%02x", bus->number); 392 } 393 bus->procdir = proc_mkdir(name, proc_bus_pci_dir); 394 if (!bus->procdir) 395 return -ENOMEM; 396 } 397 398 sprintf(name, "%02x.%x", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 399 e = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, bus->procdir, 400 &proc_bus_pci_operations, dev); 401 if (!e) 402 return -ENOMEM; 403 proc_set_size(e, dev->cfg_size); 404 dev->procent = e; 405 406 return 0; 407 } 408 409 int pci_proc_detach_device(struct pci_dev *dev) 410 { 411 proc_remove(dev->procent); 412 dev->procent = NULL; 413 return 0; 414 } 415 416 int pci_proc_detach_bus(struct pci_bus* bus) 417 { 418 proc_remove(bus->procdir); 419 return 0; 420 } 421 422 static int proc_bus_pci_dev_open(struct inode *inode, struct file *file) 423 { 424 return seq_open(file, &proc_bus_pci_devices_op); 425 } 426 static const struct file_operations proc_bus_pci_dev_operations = { 427 .owner = THIS_MODULE, 428 .open = proc_bus_pci_dev_open, 429 .read = seq_read, 430 .llseek = seq_lseek, 431 .release = seq_release, 432 }; 433 434 static int __init pci_proc_init(void) 435 { 436 struct pci_dev *dev = NULL; 437 proc_bus_pci_dir = proc_mkdir("bus/pci", NULL); 438 proc_create("devices", 0, proc_bus_pci_dir, 439 &proc_bus_pci_dev_operations); 440 proc_initialized = 1; 441 for_each_pci_dev(dev) 442 pci_proc_attach_device(dev); 443 444 return 0; 445 } 446 447 device_initcall(pci_proc_init); 448 449