2 * $Id: proc.c,v 1.13 1998/05/12 07:36:07 mj Exp $
4 * Procfs interface for the PCI bus.
6 * Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
9 #include <linux/config.h>
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/pci.h>
13 #include <linux/proc_fs.h>
14 #include <linux/init.h>
15 #include <asm/uaccess.h>
16 #include <asm/byteorder.h>
18 #define PCI_CFG_SPACE_SIZE 256
21 proc_bus_pci_lseek(struct file
*file
, loff_t off
, int whence
)
30 new = file
->f_pos
+ off
;
33 new = PCI_CFG_SPACE_SIZE
+ off
;
38 if (new < 0 || new > PCI_CFG_SPACE_SIZE
)
40 return (file
->f_pos
= new);
44 proc_bus_pci_read(struct file
*file
, char *buf
, size_t nbytes
, loff_t
*ppos
)
46 struct inode
*ino
= file
->f_dentry
->d_inode
;
47 struct proc_dir_entry
*dp
= ino
->u
.generic_ip
;
48 struct pci_dev
*dev
= dp
->data
;
50 unsigned char bus
= dev
->bus
->number
;
51 unsigned char dfn
= dev
->devfn
;
55 * Normal users can read only the standardized portion of the
56 * configuration space as several chips lock up when trying to read
57 * undefined locations (think of Intel PIIX4 as a typical example).
60 if (capable(CAP_SYS_ADMIN
))
61 size
= PCI_CFG_SPACE_SIZE
;
62 else if (dev
->hdr_type
== PCI_HEADER_TYPE_CARDBUS
)
71 if (pos
+ nbytes
> size
)
75 if (!access_ok(VERIFY_WRITE
, buf
, cnt
))
78 if ((pos
& 1) && cnt
) {
80 pcibios_read_config_byte(bus
, dfn
, pos
, &val
);
87 if ((pos
& 3) && cnt
> 2) {
89 pcibios_read_config_word(bus
, dfn
, pos
, &val
);
90 __put_user(cpu_to_le16(val
), (unsigned short *) buf
);
98 pcibios_read_config_dword(bus
, dfn
, pos
, &val
);
99 __put_user(cpu_to_le32(val
), (unsigned int *) buf
);
107 pcibios_read_config_word(bus
, dfn
, pos
, &val
);
108 __put_user(cpu_to_le16(val
), (unsigned short *) buf
);
116 pcibios_read_config_byte(bus
, dfn
, pos
, &val
);
117 __put_user(val
, buf
);
128 proc_bus_pci_write(struct file
*file
, const char *buf
, size_t nbytes
, loff_t
*ppos
)
130 struct inode
*ino
= file
->f_dentry
->d_inode
;
131 struct proc_dir_entry
*dp
= ino
->u
.generic_ip
;
132 struct pci_dev
*dev
= dp
->data
;
134 unsigned char bus
= dev
->bus
->number
;
135 unsigned char dfn
= dev
->devfn
;
138 if (pos
>= PCI_CFG_SPACE_SIZE
)
140 if (nbytes
>= PCI_CFG_SPACE_SIZE
)
141 nbytes
= PCI_CFG_SPACE_SIZE
;
142 if (pos
+ nbytes
> PCI_CFG_SPACE_SIZE
)
143 nbytes
= PCI_CFG_SPACE_SIZE
- pos
;
146 if (!access_ok(VERIFY_READ
, buf
, cnt
))
149 if ((pos
& 1) && cnt
) {
151 __get_user(val
, buf
);
152 pcibios_write_config_byte(bus
, dfn
, pos
, val
);
158 if ((pos
& 3) && cnt
> 2) {
160 __get_user(val
, (unsigned short *) buf
);
161 pcibios_write_config_word(bus
, dfn
, pos
, le16_to_cpu(val
));
169 __get_user(val
, (unsigned int *) buf
);
170 pcibios_write_config_dword(bus
, dfn
, pos
, le32_to_cpu(val
));
178 __get_user(val
, (unsigned short *) buf
);
179 pcibios_write_config_word(bus
, dfn
, pos
, le16_to_cpu(val
));
187 __get_user(val
, buf
);
188 pcibios_write_config_byte(bus
, dfn
, pos
, val
);
198 static struct file_operations proc_bus_pci_operations
= {
206 NULL
, /* no special open code */
208 NULL
, /* no special release code */
209 NULL
/* can't fsync */
212 static struct inode_operations proc_bus_pci_inode_operations
= {
213 &proc_bus_pci_operations
, /* default base directory file-ops */
224 NULL
, /* follow_link */
226 NULL
, /* writepage */
229 NULL
/* permission */
233 get_pci_dev_info(char *buf
, char **start
, off_t pos
, int count
, int wr
)
235 struct pci_dev
*dev
= pci_devices
;
240 while (dev
&& count
> cnt
) {
241 len
= sprintf(buf
, "%02x%02x\t%04x%04x\t%x",
248 len
+= sprintf(buf
+len
,
249 #if BITS_PER_LONG == 32
254 dev
->base_address
[i
]);
255 len
+= sprintf(buf
+len
,
256 #if BITS_PER_LONG == 32
266 *start
= buf
+ (pos
- (at
- len
));
274 return (count
> cnt
) ? cnt
: count
;
277 static struct proc_dir_entry proc_pci_devices
= {
278 PROC_BUS_PCI_DEVICES
, 7, "devices",
279 S_IFREG
| S_IRUGO
, 1, 0, 0,
280 0, &proc_array_inode_operations
,
284 static struct proc_dir_entry
*proc_bus_pci_dir
;
286 int pci_proc_attach_device(struct pci_dev
*dev
)
288 struct pci_bus
*bus
= dev
->bus
;
289 struct proc_dir_entry
*de
, *e
;
292 if (!(de
= bus
->procdir
)) {
293 sprintf(name
, "%02x", bus
->number
);
294 de
= bus
->procdir
= create_proc_entry(name
, S_IFDIR
, proc_bus_pci_dir
);
298 sprintf(name
, "%02x.%x", PCI_SLOT(dev
->devfn
), PCI_FUNC(dev
->devfn
));
299 e
= dev
->procent
= create_proc_entry(name
, S_IFREG
| S_IRUGO
| S_IWUSR
, de
);
302 e
->ops
= &proc_bus_pci_inode_operations
;
304 e
->size
= PCI_CFG_SPACE_SIZE
;
308 int pci_proc_detach_device(struct pci_dev
*dev
)
310 struct proc_dir_entry
*e
;
312 if ((e
= dev
->procent
)) {
315 remove_proc_entry(e
->name
, dev
->bus
->procdir
);
321 __initfunc(void proc_bus_pci_add(struct pci_bus
*bus
))
326 for(dev
= bus
->devices
; dev
; dev
= dev
->sibling
)
327 pci_proc_attach_device(dev
);
329 proc_bus_pci_add(bus
->children
);
334 __initfunc(void pci_proc_init(void))
338 proc_bus_pci_dir
= create_proc_entry("pci", S_IFDIR
, proc_bus
);
339 proc_register(proc_bus_pci_dir
, &proc_pci_devices
);
340 proc_bus_pci_add(&pci_root
);
342 #ifdef CONFIG_PCI_OLD_PROC