OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [pci/] [pci-sysfs.c] - Blame information for rev 65

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.