2 * The PCI Library -- Configuration Access via /proc/bus/pci
4 * Copyright (c) 1997--2003 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
16 #include <sys/types.h>
22 proc_config(struct pci_access
*a
)
24 pci_define_param(a
, "proc.path", PCI_PATH_PROC_BUS_PCI
, "Path to the procfs bus tree");
28 proc_detect(struct pci_access
*a
)
30 char *name
= pci_get_param(a
, "proc.path");
32 if (access(name
, R_OK
))
34 a
->warning("Cannot open %s", name
);
37 a
->debug("...using %s", name
);
42 proc_init(struct pci_access
*a
)
48 proc_cleanup(struct pci_access
*a
)
58 proc_scan(struct pci_access
*a
)
63 if (snprintf(buf
, sizeof(buf
), "%s/devices", pci_get_param(a
, "proc.path")) == sizeof(buf
))
64 a
->error("File name too long");
67 a
->error("Cannot open %s", buf
);
68 while (fgets(buf
, sizeof(buf
)-1, f
))
70 struct pci_dev
*d
= pci_alloc_dev(a
);
71 unsigned int dfn
, vend
, cnt
, known
;
73 #define F " " PCIADDR_T_FMT
74 cnt
= sscanf(buf
, "%x %x %x" F F F F F F F F F F F F F F
,
93 if (cnt
!= 9 && cnt
!= 10 && cnt
!= 17)
94 a
->error("proc: parse error (read only %d items)", cnt
);
96 d
->dev
= PCI_SLOT(dfn
& 0xff);
97 d
->func
= PCI_FUNC(dfn
& 0xff);
98 d
->vendor_id
= vend
>> 16U;
99 d
->device_id
= vend
& 0xffff;
103 known
|= PCI_FILL_IDENT
| PCI_FILL_IRQ
| PCI_FILL_BASES
;
105 known
|= PCI_FILL_ROM_BASE
;
107 known
|= PCI_FILL_SIZES
;
109 d
->known_fields
= known
;
116 proc_setup(struct pci_dev
*d
, int rw
)
118 struct pci_access
*a
= d
->access
;
120 if (a
->cached_dev
!= d
|| a
->fd_rw
< rw
)
126 e
= snprintf(buf
, sizeof(buf
), "%s/%02x/%02x.%d",
127 pci_get_param(a
, "proc.path"),
128 d
->bus
, d
->dev
, d
->func
);
129 if (e
< 0 || e
>= (int) sizeof(buf
))
130 a
->error("File name too long");
131 a
->fd_rw
= a
->writeable
|| rw
;
132 a
->fd
= open(buf
, a
->fd_rw
? O_RDWR
: O_RDONLY
);
135 e
= snprintf(buf
, sizeof(buf
), "%s/%04x:%02x/%02x.%d",
136 pci_get_param(a
, "proc.path"),
137 d
->domain
, d
->bus
, d
->dev
, d
->func
);
138 if (e
< 0 || e
>= (int) sizeof(buf
))
139 a
->error("File name too long");
140 a
->fd
= open(buf
, a
->fd_rw
? O_RDWR
: O_RDONLY
);
143 a
->warning("Cannot open %s", buf
);
151 proc_read(struct pci_dev
*d
, int pos
, byte
*buf
, int len
)
153 int fd
= proc_setup(d
, 0);
158 res
= do_read(d
, fd
, buf
, len
, pos
);
161 d
->access
->warning("proc_read: read failed: %s", strerror(errno
));
170 proc_write(struct pci_dev
*d
, int pos
, byte
*buf
, int len
)
172 int fd
= proc_setup(d
, 1);
177 res
= do_write(d
, fd
, buf
, len
, pos
);
180 d
->access
->warning("proc_write: write failed: %s", strerror(errno
));
185 d
->access
->warning("proc_write: tried to write %d bytes at %d, but only %d succeeded", len
, pos
, res
);
192 proc_cleanup_dev(struct pci_dev
*d
)
194 if (d
->access
->cached_dev
== d
)
195 d
->access
->cached_dev
= NULL
;
198 struct pci_methods pm_linux_proc
= {
200 "The proc file system on Linux",
206 pci_generic_fill_info
,