Merge branch 'i2c-fix' of git://aeryn.fluff.org.uk/bjdooks/linux
[pandora-kernel.git] / drivers / pci / pci-sysfs.c
1 /*
2  * drivers/pci/pci-sysfs.c
3  *
4  * (C) Copyright 2002-2004 Greg Kroah-Hartman <greg@kroah.com>
5  * (C) Copyright 2002-2004 IBM Corp.
6  * (C) Copyright 2003 Matthew Wilcox
7  * (C) Copyright 2003 Hewlett-Packard
8  * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
9  * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
10  *
11  * File attributes for PCI devices
12  *
13  * Modeled after usb's driverfs.c 
14  *
15  */
16
17
18 #include <linux/kernel.h>
19 #include <linux/pci.h>
20 #include <linux/stat.h>
21 #include <linux/topology.h>
22 #include <linux/mm.h>
23 #include <linux/capability.h>
24 #include <linux/pci-aspm.h>
25 #include "pci.h"
26
27 static int sysfs_initialized;   /* = 0 */
28
29 /* show configuration fields */
30 #define pci_config_attr(field, format_string)                           \
31 static ssize_t                                                          \
32 field##_show(struct device *dev, struct device_attribute *attr, char *buf)                              \
33 {                                                                       \
34         struct pci_dev *pdev;                                           \
35                                                                         \
36         pdev = to_pci_dev (dev);                                        \
37         return sprintf (buf, format_string, pdev->field);               \
38 }
39
40 pci_config_attr(vendor, "0x%04x\n");
41 pci_config_attr(device, "0x%04x\n");
42 pci_config_attr(subsystem_vendor, "0x%04x\n");
43 pci_config_attr(subsystem_device, "0x%04x\n");
44 pci_config_attr(class, "0x%06x\n");
45 pci_config_attr(irq, "%u\n");
46
47 static ssize_t broken_parity_status_show(struct device *dev,
48                                          struct device_attribute *attr,
49                                          char *buf)
50 {
51         struct pci_dev *pdev = to_pci_dev(dev);
52         return sprintf (buf, "%u\n", pdev->broken_parity_status);
53 }
54
55 static ssize_t broken_parity_status_store(struct device *dev,
56                                           struct device_attribute *attr,
57                                           const char *buf, size_t count)
58 {
59         struct pci_dev *pdev = to_pci_dev(dev);
60         ssize_t consumed = -EINVAL;
61
62         if ((count > 0) && (*buf == '0' || *buf == '1')) {
63                 pdev->broken_parity_status = *buf == '1' ? 1 : 0;
64                 consumed = count;
65         }
66         return consumed;
67 }
68
69 static ssize_t local_cpus_show(struct device *dev,
70                         struct device_attribute *attr, char *buf)
71 {               
72         cpumask_t mask;
73         int len;
74
75         mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
76         len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
77         buf[len++] = '\n';
78         buf[len] = '\0';
79         return len;
80 }
81
82
83 static ssize_t local_cpulist_show(struct device *dev,
84                         struct device_attribute *attr, char *buf)
85 {
86         cpumask_t mask;
87         int len;
88
89         mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
90         len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask);
91         buf[len++] = '\n';
92         buf[len] = '\0';
93         return len;
94 }
95
96 /* show resources */
97 static ssize_t
98 resource_show(struct device * dev, struct device_attribute *attr, char * buf)
99 {
100         struct pci_dev * pci_dev = to_pci_dev(dev);
101         char * str = buf;
102         int i;
103         int max = 7;
104         resource_size_t start, end;
105
106         if (pci_dev->subordinate)
107                 max = DEVICE_COUNT_RESOURCE;
108
109         for (i = 0; i < max; i++) {
110                 struct resource *res =  &pci_dev->resource[i];
111                 pci_resource_to_user(pci_dev, i, res, &start, &end);
112                 str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n",
113                                (unsigned long long)start,
114                                (unsigned long long)end,
115                                (unsigned long long)res->flags);
116         }
117         return (str - buf);
118 }
119
120 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
121 {
122         struct pci_dev *pci_dev = to_pci_dev(dev);
123
124         return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
125                        pci_dev->vendor, pci_dev->device,
126                        pci_dev->subsystem_vendor, pci_dev->subsystem_device,
127                        (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
128                        (u8)(pci_dev->class));
129 }
130
131 static ssize_t is_enabled_store(struct device *dev,
132                                 struct device_attribute *attr, const char *buf,
133                                 size_t count)
134 {
135         ssize_t result = -EINVAL;
136         struct pci_dev *pdev = to_pci_dev(dev);
137
138         /* this can crash the machine when done on the "wrong" device */
139         if (!capable(CAP_SYS_ADMIN))
140                 return count;
141
142         if (*buf == '0') {
143                 if (atomic_read(&pdev->enable_cnt) != 0)
144                         pci_disable_device(pdev);
145                 else
146                         result = -EIO;
147         } else if (*buf == '1')
148                 result = pci_enable_device(pdev);
149
150         return result < 0 ? result : count;
151 }
152
153 static ssize_t is_enabled_show(struct device *dev,
154                                struct device_attribute *attr, char *buf)
155 {
156         struct pci_dev *pdev;
157
158         pdev = to_pci_dev (dev);
159         return sprintf (buf, "%u\n", atomic_read(&pdev->enable_cnt));
160 }
161
162 #ifdef CONFIG_NUMA
163 static ssize_t
164 numa_node_show(struct device *dev, struct device_attribute *attr, char *buf)
165 {
166         return sprintf (buf, "%d\n", dev->numa_node);
167 }
168 #endif
169
170 static ssize_t
171 msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf)
172 {
173         struct pci_dev *pdev = to_pci_dev(dev);
174
175         if (!pdev->subordinate)
176                 return 0;
177
178         return sprintf (buf, "%u\n",
179                         !(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI));
180 }
181
182 static ssize_t
183 msi_bus_store(struct device *dev, struct device_attribute *attr,
184               const char *buf, size_t count)
185 {
186         struct pci_dev *pdev = to_pci_dev(dev);
187
188         /* bad things may happen if the no_msi flag is changed
189          * while some drivers are loaded */
190         if (!capable(CAP_SYS_ADMIN))
191                 return count;
192
193         if (!pdev->subordinate)
194                 return count;
195
196         if (*buf == '0') {
197                 pdev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
198                 dev_warn(&pdev->dev, "forced subordinate bus to not support MSI,"
199                          " bad things could happen.\n");
200         }
201
202         if (*buf == '1') {
203                 pdev->subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI;
204                 dev_warn(&pdev->dev, "forced subordinate bus to support MSI,"
205                          " bad things could happen.\n");
206         }
207
208         return count;
209 }
210
211 struct device_attribute pci_dev_attrs[] = {
212         __ATTR_RO(resource),
213         __ATTR_RO(vendor),
214         __ATTR_RO(device),
215         __ATTR_RO(subsystem_vendor),
216         __ATTR_RO(subsystem_device),
217         __ATTR_RO(class),
218         __ATTR_RO(irq),
219         __ATTR_RO(local_cpus),
220         __ATTR_RO(local_cpulist),
221         __ATTR_RO(modalias),
222 #ifdef CONFIG_NUMA
223         __ATTR_RO(numa_node),
224 #endif
225         __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
226         __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
227                 broken_parity_status_show,broken_parity_status_store),
228         __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
229         __ATTR_NULL,
230 };
231
232 static ssize_t
233 pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr,
234                 char *buf, loff_t off, size_t count)
235 {
236         struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
237         unsigned int size = 64;
238         loff_t init_off = off;
239         u8 *data = (u8*) buf;
240
241         /* Several chips lock up trying to read undefined config space */
242         if (capable(CAP_SYS_ADMIN)) {
243                 size = dev->cfg_size;
244         } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
245                 size = 128;
246         }
247
248         if (off > size)
249                 return 0;
250         if (off + count > size) {
251                 size -= off;
252                 count = size;
253         } else {
254                 size = count;
255         }
256
257         if ((off & 1) && size) {
258                 u8 val;
259                 pci_user_read_config_byte(dev, off, &val);
260                 data[off - init_off] = val;
261                 off++;
262                 size--;
263         }
264
265         if ((off & 3) && size > 2) {
266                 u16 val;
267                 pci_user_read_config_word(dev, off, &val);
268                 data[off - init_off] = val & 0xff;
269                 data[off - init_off + 1] = (val >> 8) & 0xff;
270                 off += 2;
271                 size -= 2;
272         }
273
274         while (size > 3) {
275                 u32 val;
276                 pci_user_read_config_dword(dev, off, &val);
277                 data[off - init_off] = val & 0xff;
278                 data[off - init_off + 1] = (val >> 8) & 0xff;
279                 data[off - init_off + 2] = (val >> 16) & 0xff;
280                 data[off - init_off + 3] = (val >> 24) & 0xff;
281                 off += 4;
282                 size -= 4;
283         }
284
285         if (size >= 2) {
286                 u16 val;
287                 pci_user_read_config_word(dev, off, &val);
288                 data[off - init_off] = val & 0xff;
289                 data[off - init_off + 1] = (val >> 8) & 0xff;
290                 off += 2;
291                 size -= 2;
292         }
293
294         if (size > 0) {
295                 u8 val;
296                 pci_user_read_config_byte(dev, off, &val);
297                 data[off - init_off] = val;
298                 off++;
299                 --size;
300         }
301
302         return count;
303 }
304
305 static ssize_t
306 pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr,
307                  char *buf, loff_t off, size_t count)
308 {
309         struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
310         unsigned int size = count;
311         loff_t init_off = off;
312         u8 *data = (u8*) buf;
313
314         if (off > dev->cfg_size)
315                 return 0;
316         if (off + count > dev->cfg_size) {
317                 size = dev->cfg_size - off;
318                 count = size;
319         }
320         
321         if ((off & 1) && size) {
322                 pci_user_write_config_byte(dev, off, data[off - init_off]);
323                 off++;
324                 size--;
325         }
326         
327         if ((off & 3) && size > 2) {
328                 u16 val = data[off - init_off];
329                 val |= (u16) data[off - init_off + 1] << 8;
330                 pci_user_write_config_word(dev, off, val);
331                 off += 2;
332                 size -= 2;
333         }
334
335         while (size > 3) {
336                 u32 val = data[off - init_off];
337                 val |= (u32) data[off - init_off + 1] << 8;
338                 val |= (u32) data[off - init_off + 2] << 16;
339                 val |= (u32) data[off - init_off + 3] << 24;
340                 pci_user_write_config_dword(dev, off, val);
341                 off += 4;
342                 size -= 4;
343         }
344         
345         if (size >= 2) {
346                 u16 val = data[off - init_off];
347                 val |= (u16) data[off - init_off + 1] << 8;
348                 pci_user_write_config_word(dev, off, val);
349                 off += 2;
350                 size -= 2;
351         }
352
353         if (size) {
354                 pci_user_write_config_byte(dev, off, data[off - init_off]);
355                 off++;
356                 --size;
357         }
358
359         return count;
360 }
361
362 static ssize_t
363 pci_read_vpd(struct kobject *kobj, struct bin_attribute *bin_attr,
364              char *buf, loff_t off, size_t count)
365 {
366         struct pci_dev *dev =
367                 to_pci_dev(container_of(kobj, struct device, kobj));
368         int end;
369         int ret;
370
371         if (off > bin_attr->size)
372                 count = 0;
373         else if (count > bin_attr->size - off)
374                 count = bin_attr->size - off;
375         end = off + count;
376
377         while (off < end) {
378                 ret = dev->vpd->ops->read(dev, off, end - off, buf);
379                 if (ret < 0)
380                         return ret;
381                 buf += ret;
382                 off += ret;
383         }
384
385         return count;
386 }
387
388 static ssize_t
389 pci_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr,
390               char *buf, loff_t off, size_t count)
391 {
392         struct pci_dev *dev =
393                 to_pci_dev(container_of(kobj, struct device, kobj));
394         int end;
395         int ret;
396
397         if (off > bin_attr->size)
398                 count = 0;
399         else if (count > bin_attr->size - off)
400                 count = bin_attr->size - off;
401         end = off + count;
402
403         while (off < end) {
404                 ret = dev->vpd->ops->write(dev, off, end - off, buf);
405                 if (ret < 0)
406                         return ret;
407                 buf += ret;
408                 off += ret;
409         }
410
411         return count;
412 }
413
414 #ifdef HAVE_PCI_LEGACY
415 /**
416  * pci_read_legacy_io - read byte(s) from legacy I/O port space
417  * @kobj: kobject corresponding to file to read from
418  * @buf: buffer to store results
419  * @off: offset into legacy I/O port space
420  * @count: number of bytes to read
421  *
422  * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
423  * callback routine (pci_legacy_read).
424  */
425 ssize_t
426 pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
427                    char *buf, loff_t off, size_t count)
428 {
429         struct pci_bus *bus = to_pci_bus(container_of(kobj,
430                                                       struct device,
431                                                       kobj));
432
433         /* Only support 1, 2 or 4 byte accesses */
434         if (count != 1 && count != 2 && count != 4)
435                 return -EINVAL;
436
437         return pci_legacy_read(bus, off, (u32 *)buf, count);
438 }
439
440 /**
441  * pci_write_legacy_io - write byte(s) to legacy I/O port space
442  * @kobj: kobject corresponding to file to read from
443  * @buf: buffer containing value to be written
444  * @off: offset into legacy I/O port space
445  * @count: number of bytes to write
446  *
447  * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
448  * callback routine (pci_legacy_write).
449  */
450 ssize_t
451 pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
452                     char *buf, loff_t off, size_t count)
453 {
454         struct pci_bus *bus = to_pci_bus(container_of(kobj,
455                                                       struct device,
456                                                       kobj));
457         /* Only support 1, 2 or 4 byte accesses */
458         if (count != 1 && count != 2 && count != 4)
459                 return -EINVAL;
460
461         return pci_legacy_write(bus, off, *(u32 *)buf, count);
462 }
463
464 /**
465  * pci_mmap_legacy_mem - map legacy PCI memory into user memory space
466  * @kobj: kobject corresponding to device to be mapped
467  * @attr: struct bin_attribute for this file
468  * @vma: struct vm_area_struct passed to mmap
469  *
470  * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap
471  * legacy memory space (first meg of bus space) into application virtual
472  * memory space.
473  */
474 int
475 pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
476                     struct vm_area_struct *vma)
477 {
478         struct pci_bus *bus = to_pci_bus(container_of(kobj,
479                                                       struct device,
480                                                       kobj));
481
482         return pci_mmap_legacy_page_range(bus, vma);
483 }
484 #endif /* HAVE_PCI_LEGACY */
485
486 #ifdef HAVE_PCI_MMAP
487 /**
488  * pci_mmap_resource - map a PCI resource into user memory space
489  * @kobj: kobject for mapping
490  * @attr: struct bin_attribute for the file being mapped
491  * @vma: struct vm_area_struct passed into the mmap
492  * @write_combine: 1 for write_combine mapping
493  *
494  * Use the regular PCI mapping routines to map a PCI resource into userspace.
495  */
496 static int
497 pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
498                   struct vm_area_struct *vma, int write_combine)
499 {
500         struct pci_dev *pdev = to_pci_dev(container_of(kobj,
501                                                        struct device, kobj));
502         struct resource *res = (struct resource *)attr->private;
503         enum pci_mmap_state mmap_type;
504         resource_size_t start, end;
505         int i;
506
507         for (i = 0; i < PCI_ROM_RESOURCE; i++)
508                 if (res == &pdev->resource[i])
509                         break;
510         if (i >= PCI_ROM_RESOURCE)
511                 return -ENODEV;
512
513         /* pci_mmap_page_range() expects the same kind of entry as coming
514          * from /proc/bus/pci/ which is a "user visible" value. If this is
515          * different from the resource itself, arch will do necessary fixup.
516          */
517         pci_resource_to_user(pdev, i, res, &start, &end);
518         vma->vm_pgoff += start >> PAGE_SHIFT;
519         mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
520
521         return pci_mmap_page_range(pdev, vma, mmap_type, write_combine);
522 }
523
524 static int
525 pci_mmap_resource_uc(struct kobject *kobj, struct bin_attribute *attr,
526                      struct vm_area_struct *vma)
527 {
528         return pci_mmap_resource(kobj, attr, vma, 0);
529 }
530
531 static int
532 pci_mmap_resource_wc(struct kobject *kobj, struct bin_attribute *attr,
533                      struct vm_area_struct *vma)
534 {
535         return pci_mmap_resource(kobj, attr, vma, 1);
536 }
537
538 /**
539  * pci_remove_resource_files - cleanup resource files
540  * @dev: dev to cleanup
541  *
542  * If we created resource files for @dev, remove them from sysfs and
543  * free their resources.
544  */
545 static void
546 pci_remove_resource_files(struct pci_dev *pdev)
547 {
548         int i;
549
550         for (i = 0; i < PCI_ROM_RESOURCE; i++) {
551                 struct bin_attribute *res_attr;
552
553                 res_attr = pdev->res_attr[i];
554                 if (res_attr) {
555                         sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
556                         kfree(res_attr);
557                 }
558
559                 res_attr = pdev->res_attr_wc[i];
560                 if (res_attr) {
561                         sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
562                         kfree(res_attr);
563                 }
564         }
565 }
566
567 static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
568 {
569         /* allocate attribute structure, piggyback attribute name */
570         int name_len = write_combine ? 13 : 10;
571         struct bin_attribute *res_attr;
572         int retval;
573
574         res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
575         if (res_attr) {
576                 char *res_attr_name = (char *)(res_attr + 1);
577
578                 if (write_combine) {
579                         pdev->res_attr_wc[num] = res_attr;
580                         sprintf(res_attr_name, "resource%d_wc", num);
581                         res_attr->mmap = pci_mmap_resource_wc;
582                 } else {
583                         pdev->res_attr[num] = res_attr;
584                         sprintf(res_attr_name, "resource%d", num);
585                         res_attr->mmap = pci_mmap_resource_uc;
586                 }
587                 res_attr->attr.name = res_attr_name;
588                 res_attr->attr.mode = S_IRUSR | S_IWUSR;
589                 res_attr->size = pci_resource_len(pdev, num);
590                 res_attr->private = &pdev->resource[num];
591                 retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
592         } else
593                 retval = -ENOMEM;
594
595         return retval;
596 }
597
598 /**
599  * pci_create_resource_files - create resource files in sysfs for @dev
600  * @dev: dev in question
601  *
602  * Walk the resources in @dev creating files for each resource available.
603  */
604 static int pci_create_resource_files(struct pci_dev *pdev)
605 {
606         int i;
607         int retval;
608
609         /* Expose the PCI resources from this device as files */
610         for (i = 0; i < PCI_ROM_RESOURCE; i++) {
611
612                 /* skip empty resources */
613                 if (!pci_resource_len(pdev, i))
614                         continue;
615
616                 retval = pci_create_attr(pdev, i, 0);
617                 /* for prefetchable resources, create a WC mappable file */
618                 if (!retval && pdev->resource[i].flags & IORESOURCE_PREFETCH)
619                         retval = pci_create_attr(pdev, i, 1);
620
621                 if (retval) {
622                         pci_remove_resource_files(pdev);
623                         return retval;
624                 }
625         }
626         return 0;
627 }
628 #else /* !HAVE_PCI_MMAP */
629 static inline int pci_create_resource_files(struct pci_dev *dev) { return 0; }
630 static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
631 #endif /* HAVE_PCI_MMAP */
632
633 /**
634  * pci_write_rom - used to enable access to the PCI ROM display
635  * @kobj: kernel object handle
636  * @buf: user input
637  * @off: file offset
638  * @count: number of byte in input
639  *
640  * writing anything except 0 enables it
641  */
642 static ssize_t
643 pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
644               char *buf, loff_t off, size_t count)
645 {
646         struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
647
648         if ((off ==  0) && (*buf == '0') && (count == 2))
649                 pdev->rom_attr_enabled = 0;
650         else
651                 pdev->rom_attr_enabled = 1;
652
653         return count;
654 }
655
656 /**
657  * pci_read_rom - read a PCI ROM
658  * @kobj: kernel object handle
659  * @buf: where to put the data we read from the ROM
660  * @off: file offset
661  * @count: number of bytes to read
662  *
663  * Put @count bytes starting at @off into @buf from the ROM in the PCI
664  * device corresponding to @kobj.
665  */
666 static ssize_t
667 pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
668              char *buf, loff_t off, size_t count)
669 {
670         struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
671         void __iomem *rom;
672         size_t size;
673
674         if (!pdev->rom_attr_enabled)
675                 return -EINVAL;
676         
677         rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */
678         if (!rom)
679                 return 0;
680                 
681         if (off >= size)
682                 count = 0;
683         else {
684                 if (off + count > size)
685                         count = size - off;
686                 
687                 memcpy_fromio(buf, rom + off, count);
688         }
689         pci_unmap_rom(pdev, rom);
690                 
691         return count;
692 }
693
694 static struct bin_attribute pci_config_attr = {
695         .attr = {
696                 .name = "config",
697                 .mode = S_IRUGO | S_IWUSR,
698         },
699         .size = 256,
700         .read = pci_read_config,
701         .write = pci_write_config,
702 };
703
704 static struct bin_attribute pcie_config_attr = {
705         .attr = {
706                 .name = "config",
707                 .mode = S_IRUGO | S_IWUSR,
708         },
709         .size = 4096,
710         .read = pci_read_config,
711         .write = pci_write_config,
712 };
713
714 int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev)
715 {
716         return 0;
717 }
718
719 int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
720 {
721         struct bin_attribute *attr = NULL;
722         int retval;
723
724         if (!sysfs_initialized)
725                 return -EACCES;
726
727         if (pdev->cfg_size < 4096)
728                 retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
729         else
730                 retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
731         if (retval)
732                 goto err;
733
734         /* If the device has VPD, try to expose it in sysfs. */
735         if (pdev->vpd) {
736                 attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
737                 if (attr) {
738                         pdev->vpd->attr = attr;
739                         attr->size = pdev->vpd->ops->get_size(pdev);
740                         attr->attr.name = "vpd";
741                         attr->attr.mode = S_IRUGO | S_IWUSR;
742                         attr->read = pci_read_vpd;
743                         attr->write = pci_write_vpd;
744                         retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
745                         if (retval)
746                                 goto err_vpd;
747                 } else {
748                         retval = -ENOMEM;
749                         goto err_config_file;
750                 }
751         }
752
753         retval = pci_create_resource_files(pdev);
754         if (retval)
755                 goto err_vpd_file;
756
757         /* If the device has a ROM, try to expose it in sysfs. */
758         if (pci_resource_len(pdev, PCI_ROM_RESOURCE) ||
759             (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) {
760                 attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
761                 if (attr) {
762                         pdev->rom_attr = attr;
763                         attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
764                         attr->attr.name = "rom";
765                         attr->attr.mode = S_IRUSR;
766                         attr->read = pci_read_rom;
767                         attr->write = pci_write_rom;
768                         retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
769                         if (retval)
770                                 goto err_rom;
771                 } else {
772                         retval = -ENOMEM;
773                         goto err_resource_files;
774                 }
775         }
776         /* add platform-specific attributes */
777         if (pcibios_add_platform_entries(pdev))
778                 goto err_rom_file;
779
780         pcie_aspm_create_sysfs_dev_files(pdev);
781
782         return 0;
783
784 err_rom_file:
785         if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
786                 sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
787 err_rom:
788         kfree(pdev->rom_attr);
789 err_resource_files:
790         pci_remove_resource_files(pdev);
791 err_vpd_file:
792         if (pdev->vpd) {
793                 sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr);
794 err_vpd:
795                 kfree(pdev->vpd->attr);
796         }
797 err_config_file:
798         if (pdev->cfg_size < 4096)
799                 sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
800         else
801                 sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
802 err:
803         return retval;
804 }
805
806 /**
807  * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
808  * @pdev: device whose entries we should free
809  *
810  * Cleanup when @pdev is removed from sysfs.
811  */
812 void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
813 {
814         if (!sysfs_initialized)
815                 return;
816
817         pcie_aspm_remove_sysfs_dev_files(pdev);
818
819         if (pdev->vpd) {
820                 sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr);
821                 kfree(pdev->vpd->attr);
822         }
823         if (pdev->cfg_size < 4096)
824                 sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
825         else
826                 sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
827
828         pci_remove_resource_files(pdev);
829
830         if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
831                 if (pdev->rom_attr) {
832                         sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
833                         kfree(pdev->rom_attr);
834                 }
835         }
836 }
837
838 static int __init pci_sysfs_init(void)
839 {
840         struct pci_dev *pdev = NULL;
841         int retval;
842
843         sysfs_initialized = 1;
844         for_each_pci_dev(pdev) {
845                 retval = pci_create_sysfs_dev_files(pdev);
846                 if (retval) {
847                         pci_dev_put(pdev);
848                         return retval;
849                 }
850         }
851
852         return 0;
853 }
854
855 late_initcall(pci_sysfs_init);