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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [pci/] [syscall.c] - Blame information for rev 78

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

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

powered by: WebSVN 2.1.0

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