1/* 2 * $Id: proc.c,v 1.1.1.1 2008/10/15 03:26:46 james26_jang Exp $ 3 * 4 * Procfs interface for the PCI bus. 5 * 6 * Copyright (c) 1997--1999 Martin Mares <mj@ucw.cz> 7 */ 8 9#include <linux/types.h> 10#include <linux/kernel.h> 11#include <linux/pci.h> 12#include <linux/proc_fs.h> 13#include <linux/init.h> 14#include <linux/seq_file.h> 15 16#include <asm/uaccess.h> 17#include <asm/byteorder.h> 18 19#define PCI_CFG_SPACE_SIZE 256 20 21static loff_t 22proc_bus_pci_lseek(struct file *file, loff_t off, int whence) 23{ 24 loff_t new; 25 26 switch (whence) { 27 case 0: 28 new = off; 29 break; 30 case 1: 31 new = file->f_pos + off; 32 break; 33 case 2: 34 new = PCI_CFG_SPACE_SIZE + off; 35 break; 36 default: 37 return -EINVAL; 38 } 39 if (new < 0 || new > PCI_CFG_SPACE_SIZE) 40 return -EINVAL; 41 return (file->f_pos = new); 42} 43 44static ssize_t 45proc_bus_pci_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) 46{ 47 const struct inode *ino = file->f_dentry->d_inode; 48 const struct proc_dir_entry *dp = ino->u.generic_ip; 49 struct pci_dev *dev = dp->data; 50 unsigned int pos = *ppos; 51 unsigned int cnt, size; 52 53 /* 54 * Normal users can read only the standardized portion of the 55 * configuration space as several chips lock up when trying to read 56 * undefined locations (think of Intel PIIX4 as a typical example). 57 */ 58 59 if (capable(CAP_SYS_ADMIN)) 60 size = PCI_CFG_SPACE_SIZE; 61 else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 62 size = 128; 63 else 64 size = 64; 65 66 if (pos >= size) 67 return 0; 68 if (nbytes >= size) 69 nbytes = size; 70 if (pos + nbytes > size) 71 nbytes = size - pos; 72 cnt = nbytes; 73 74 if (!access_ok(VERIFY_WRITE, buf, cnt)) 75 return -EINVAL; 76 77 if ((pos & 1) && cnt) { 78 unsigned char val; 79 pci_read_config_byte(dev, pos, &val); 80 __put_user(val, buf); 81 buf++; 82 pos++; 83 cnt--; 84 } 85 86 if ((pos & 3) && cnt > 2) { 87 unsigned short val; 88 pci_read_config_word(dev, pos, &val); 89 __put_user(cpu_to_le16(val), (unsigned short *) buf); 90 buf += 2; 91 pos += 2; 92 cnt -= 2; 93 } 94 95 while (cnt >= 4) { 96 unsigned int val; 97 pci_read_config_dword(dev, pos, &val); 98 __put_user(cpu_to_le32(val), (unsigned int *) buf); 99 buf += 4; 100 pos += 4; 101 cnt -= 4; 102 } 103 104 if (cnt >= 2) { 105 unsigned short val; 106 pci_read_config_word(dev, pos, &val); 107 __put_user(cpu_to_le16(val), (unsigned short *) buf); 108 buf += 2; 109 pos += 2; 110 cnt -= 2; 111 } 112 113 if (cnt) { 114 unsigned char val; 115 pci_read_config_byte(dev, pos, &val); 116 __put_user(val, buf); 117 buf++; 118 pos++; 119 cnt--; 120 } 121 122 *ppos = pos; 123 return nbytes; 124} 125 126static ssize_t 127proc_bus_pci_write(struct file *file, const char *buf, size_t nbytes, loff_t *ppos) 128{ 129 const struct inode *ino = file->f_dentry->d_inode; 130 const struct proc_dir_entry *dp = ino->u.generic_ip; 131 struct pci_dev *dev = dp->data; 132 int pos = *ppos; 133 int cnt; 134 135 if (pos >= PCI_CFG_SPACE_SIZE) 136 return 0; 137 if (nbytes >= PCI_CFG_SPACE_SIZE) 138 nbytes = PCI_CFG_SPACE_SIZE; 139 if (pos + nbytes > PCI_CFG_SPACE_SIZE) 140 nbytes = PCI_CFG_SPACE_SIZE - pos; 141 cnt = nbytes; 142 143 if (!access_ok(VERIFY_READ, buf, cnt)) 144 return -EINVAL; 145 146 if ((pos & 1) && cnt) { 147 unsigned char val; 148 __get_user(val, buf); 149 pci_write_config_byte(dev, pos, val); 150 buf++; 151 pos++; 152 cnt--; 153 } 154 155 if ((pos & 3) && cnt > 2) { 156 unsigned short val; 157 __get_user(val, (unsigned short *) buf); 158 pci_write_config_word(dev, pos, le16_to_cpu(val)); 159 buf += 2; 160 pos += 2; 161 cnt -= 2; 162 } 163 164 while (cnt >= 4) { 165 unsigned int val; 166 __get_user(val, (unsigned int *) buf); 167 pci_write_config_dword(dev, pos, le32_to_cpu(val)); 168 buf += 4; 169 pos += 4; 170 cnt -= 4; 171 } 172 173 if (cnt >= 2) { 174 unsigned short val; 175 __get_user(val, (unsigned short *) buf); 176 pci_write_config_word(dev, pos, le16_to_cpu(val)); 177 buf += 2; 178 pos += 2; 179 cnt -= 2; 180 } 181 182 if (cnt) { 183 unsigned char val; 184 __get_user(val, buf); 185 pci_write_config_byte(dev, pos, val); 186 buf++; 187 pos++; 188 cnt--; 189 } 190 191 *ppos = pos; 192 return nbytes; 193} 194 195struct pci_filp_private { 196 enum pci_mmap_state mmap_state; 197 int write_combine; 198}; 199 200static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 201{ 202 const struct proc_dir_entry *dp = inode->u.generic_ip; 203 struct pci_dev *dev = dp->data; 204#ifdef HAVE_PCI_MMAP 205 struct pci_filp_private *fpriv = file->private_data; 206#endif /* HAVE_PCI_MMAP */ 207 int ret = 0; 208 209 switch (cmd) { 210 case PCIIOC_CONTROLLER: 211 ret = pci_controller_num(dev); 212 break; 213 214#ifdef HAVE_PCI_MMAP 215 case PCIIOC_MMAP_IS_IO: 216 fpriv->mmap_state = pci_mmap_io; 217 break; 218 219 case PCIIOC_MMAP_IS_MEM: 220 fpriv->mmap_state = pci_mmap_mem; 221 break; 222 223 case PCIIOC_WRITE_COMBINE: 224 if (arg) 225 fpriv->write_combine = 1; 226 else 227 fpriv->write_combine = 0; 228 break; 229 230#endif /* HAVE_PCI_MMAP */ 231 232 default: 233 ret = -EINVAL; 234 break; 235 }; 236 237 return ret; 238} 239 240#ifdef HAVE_PCI_MMAP 241static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) 242{ 243 struct inode *inode = file->f_dentry->d_inode; 244 const struct proc_dir_entry *dp = inode->u.generic_ip; 245 struct pci_dev *dev = dp->data; 246 struct pci_filp_private *fpriv = file->private_data; 247 int ret; 248 249 if (!capable(CAP_SYS_RAWIO)) 250 return -EPERM; 251 252 ret = pci_mmap_page_range(dev, vma, 253 fpriv->mmap_state, 254 fpriv->write_combine); 255 if (ret < 0) 256 return ret; 257 258 return 0; 259} 260 261static int proc_bus_pci_open(struct inode *inode, struct file *file) 262{ 263 struct pci_filp_private *fpriv = kmalloc(sizeof(*fpriv), GFP_KERNEL); 264 265 if (!fpriv) 266 return -ENOMEM; 267 268 fpriv->mmap_state = pci_mmap_io; 269 fpriv->write_combine = 0; 270 271 file->private_data = fpriv; 272 273 return 0; 274} 275 276static int proc_bus_pci_release(struct inode *inode, struct file *file) 277{ 278 kfree(file->private_data); 279 file->private_data = NULL; 280 281 return 0; 282} 283#endif /* HAVE_PCI_MMAP */ 284 285static struct file_operations proc_bus_pci_operations = { 286 llseek: proc_bus_pci_lseek, 287 read: proc_bus_pci_read, 288 write: proc_bus_pci_write, 289 ioctl: proc_bus_pci_ioctl, 290#ifdef HAVE_PCI_MMAP 291 open: proc_bus_pci_open, 292 release: proc_bus_pci_release, 293 mmap: proc_bus_pci_mmap, 294#ifdef HAVE_ARCH_PCI_GET_UNMAPPED_AREA 295 get_unmapped_area: get_pci_unmapped_area, 296#endif /* HAVE_ARCH_PCI_GET_UNMAPPED_AREA */ 297#endif /* HAVE_PCI_MMAP */ 298}; 299 300#if BITS_PER_LONG == 32 301#define LONG_FORMAT "\t%08lx" 302#else 303#define LONG_FORMAT "\t%16lx" 304#endif 305 306/* iterator */ 307static void *pci_seq_start(struct seq_file *m, loff_t *pos) 308{ 309 struct list_head *p = &pci_devices; 310 loff_t n = *pos; 311 312 while (n--) { 313 p = p->next; 314 if (p == &pci_devices) 315 return NULL; 316 } 317 return p; 318} 319static void *pci_seq_next(struct seq_file *m, void *v, loff_t *pos) 320{ 321 struct list_head *p = v; 322 (*pos)++; 323 return p->next != &pci_devices ? p->next : NULL; 324} 325static void pci_seq_stop(struct seq_file *m, void *v) 326{ 327 /* release whatever locks we need */ 328} 329 330static int show_device(struct seq_file *m, void *v) 331{ 332 struct list_head *p = v; 333 const struct pci_dev *dev; 334 const struct pci_driver *drv; 335 int i; 336 337 if (p == &pci_devices) 338 return 0; 339 340 dev = pci_dev_g(p); 341 drv = pci_dev_driver(dev); 342 seq_printf(m, "%02x%02x\t%04x%04x\t%x", 343 dev->bus->number, 344 dev->devfn, 345 dev->vendor, 346 dev->device, 347 dev->irq); 348 /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ 349 for(i=0; i<7; i++) 350 seq_printf(m, LONG_FORMAT, 351 dev->resource[i].start | 352 (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); 353 for(i=0; i<7; i++) 354 seq_printf(m, LONG_FORMAT, 355 dev->resource[i].start < dev->resource[i].end ? 356 dev->resource[i].end - dev->resource[i].start + 1 : 0); 357 seq_putc(m, '\t'); 358 if (drv) 359 seq_printf(m, "%s", drv->name); 360 seq_putc(m, '\n'); 361 return 0; 362} 363 364static struct seq_operations proc_bus_pci_devices_op = { 365 start: pci_seq_start, 366 next: pci_seq_next, 367 stop: pci_seq_stop, 368 show: show_device 369}; 370 371struct proc_dir_entry *proc_bus_pci_dir; 372 373int pci_proc_attach_device(struct pci_dev *dev) 374{ 375 struct pci_bus *bus = dev->bus; 376 struct proc_dir_entry *de, *e; 377 char name[16]; 378 379 if (!(de = bus->procdir)) { 380 sprintf(name, "%02x", bus->number); 381 de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir); 382 if (!de) 383 return -ENOMEM; 384 } 385 sprintf(name, "%02x.%x", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 386 e = dev->procent = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, de); 387 if (!e) 388 return -ENOMEM; 389 e->proc_fops = &proc_bus_pci_operations; 390 e->data = dev; 391 e->size = PCI_CFG_SPACE_SIZE; 392 return 0; 393} 394 395int pci_proc_detach_device(struct pci_dev *dev) 396{ 397 struct proc_dir_entry *e; 398 399 if ((e = dev->procent)) { 400 if (atomic_read(&e->count)) 401 return -EBUSY; 402 remove_proc_entry(e->name, dev->bus->procdir); 403 dev->procent = NULL; 404 } 405 return 0; 406} 407 408int pci_proc_attach_bus(struct pci_bus* bus) 409{ 410 struct proc_dir_entry *de = bus->procdir; 411 412 if (!de) { 413 char name[16]; 414 sprintf(name, "%02x", bus->number); 415 de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir); 416 if (!de) 417 return -ENOMEM; 418 } 419 return 0; 420} 421 422int pci_proc_detach_bus(struct pci_bus* bus) 423{ 424 struct proc_dir_entry *de = bus->procdir; 425 if (de) 426 remove_proc_entry(de->name, proc_bus_pci_dir); 427 return 0; 428} 429 430 431/* 432 * Backward compatible /proc/pci interface. 433 */ 434 435/* 436 * Convert some of the configuration space registers of the device at 437 * address (bus,devfn) into a string (possibly several lines each). 438 * The configuration string is stored starting at buf[len]. If the 439 * string would exceed the size of the buffer (SIZE), 0 is returned. 440 */ 441static int show_dev_config(struct seq_file *m, void *v) 442{ 443 struct list_head *p = v; 444 struct pci_dev *dev; 445 struct pci_driver *drv; 446 u32 class_rev; 447 unsigned char latency, min_gnt, max_lat, *class; 448 int reg; 449 450 if (p == &pci_devices) { 451 seq_puts(m, "PCI devices found:\n"); 452 return 0; 453 } 454 455 dev = pci_dev_g(p); 456 drv = pci_dev_driver(dev); 457 458 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); 459 pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); 460 pci_read_config_byte (dev, PCI_MIN_GNT, &min_gnt); 461 pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat); 462 seq_printf(m, " Bus %2d, device %3d, function %2d:\n", 463 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 464 class = pci_class_name(class_rev >> 16); 465 if (class) 466 seq_printf(m, " %s", class); 467 else 468 seq_printf(m, " Class %04x", class_rev >> 16); 469 seq_printf(m, ": %s (rev %d).\n", dev->name, class_rev & 0xff); 470 471 if (dev->irq) 472 seq_printf(m, " IRQ %d.\n", dev->irq); 473 474 if (latency || min_gnt || max_lat) { 475 seq_printf(m, " Master Capable. "); 476 if (latency) 477 seq_printf(m, "Latency=%d. ", latency); 478 else 479 seq_puts(m, "No bursts. "); 480 if (min_gnt) 481 seq_printf(m, "Min Gnt=%d.", min_gnt); 482 if (max_lat) 483 seq_printf(m, "Max Lat=%d.", max_lat); 484 seq_putc(m, '\n'); 485 } 486 487 for (reg = 0; reg < 6; reg++) { 488 struct resource *res = dev->resource + reg; 489 unsigned long base, end, flags; 490 491 base = res->start; 492 end = res->end; 493 flags = res->flags; 494 if (!end) 495 continue; 496 497 if (flags & PCI_BASE_ADDRESS_SPACE_IO) { 498 seq_printf(m, " I/O at 0x%lx [0x%lx].\n", 499 base, end); 500 } else { 501 const char *pref, *type = "unknown"; 502 503 if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH) 504 pref = "P"; 505 else 506 pref = "Non-p"; 507 switch (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { 508 case PCI_BASE_ADDRESS_MEM_TYPE_32: 509 type = "32 bit"; break; 510 case PCI_BASE_ADDRESS_MEM_TYPE_1M: 511 type = "20 bit"; break; 512 case PCI_BASE_ADDRESS_MEM_TYPE_64: 513 type = "64 bit"; break; 514 } 515 seq_printf(m, " %srefetchable %s memory at " 516 "0x%lx [0x%lx].\n", pref, type, 517 base, 518 end); 519 } 520 } 521 return 0; 522} 523 524static struct seq_operations proc_pci_op = { 525 start: pci_seq_start, 526 next: pci_seq_next, 527 stop: pci_seq_stop, 528 show: show_dev_config 529}; 530 531static int proc_bus_pci_dev_open(struct inode *inode, struct file *file) 532{ 533 return seq_open(file, &proc_bus_pci_devices_op); 534} 535static struct file_operations proc_bus_pci_dev_operations = { 536 open: proc_bus_pci_dev_open, 537 read: seq_read, 538 llseek: seq_lseek, 539 release: seq_release, 540}; 541static int proc_pci_open(struct inode *inode, struct file *file) 542{ 543 return seq_open(file, &proc_pci_op); 544} 545static struct file_operations proc_pci_operations = { 546 open: proc_pci_open, 547 read: seq_read, 548 llseek: seq_lseek, 549 release: seq_release, 550}; 551 552static int __init pci_proc_init(void) 553{ 554 if (pci_present()) { 555 struct proc_dir_entry *entry; 556 struct pci_dev *dev; 557 proc_bus_pci_dir = proc_mkdir("pci", proc_bus); 558 entry = create_proc_entry("devices", 0, proc_bus_pci_dir); 559 if (entry) 560 entry->proc_fops = &proc_bus_pci_dev_operations; 561 pci_for_each_dev(dev) { 562 pci_proc_attach_device(dev); 563 } 564 entry = create_proc_entry("pci", 0, NULL); 565 if (entry) 566 entry->proc_fops = &proc_pci_operations; 567 } 568 return 0; 569} 570 571__initcall(pci_proc_init); 572