107
120
a->error("Cannot open %s: %s", namebuf, strerror(errno));
108
121
for (i = 0; i < 7; i++)
110
unsigned long long start, end, size;
123
unsigned long long start, end, size, flags;
111
124
if (!fgets(buf, sizeof(buf), file))
113
if (sscanf(buf, "%llx %llx", &start, &end) != 2)
126
if (sscanf(buf, "%llx %llx %llx", &start, &end, &flags) != 3)
114
127
a->error("Syntax error in %s", namebuf);
116
129
size = end - start + 1;
132
flags &= PCI_ADDR_FLAG_MASK;
121
d->base_addr[i] = start;
135
d->base_addr[i] = start | flags;
122
136
d->size[i] = size;
126
d->rom_base_addr = start;
140
d->rom_base_addr = start | flags;
127
141
d->rom_size = size;
181
sysfs_setup(struct pci_dev *d, int rw)
195
sysfs_fill_slots(struct pci_access *a)
199
struct dirent *entry;
202
n = snprintf(dirname, sizeof(dirname), "%s/slots", sysfs_name(a));
203
if (n < 0 || n >= (int) sizeof(dirname))
204
a->error("Directory name too long");
205
dir = opendir(dirname);
209
while (entry = readdir(dir))
211
char namebuf[OBJNAMELEN], buf[16];
213
unsigned int dom, bus, dev;
216
/* ".", ".." or a special non-device perhaps */
217
if (entry->d_name[0] == '.')
220
n = snprintf(namebuf, OBJNAMELEN, "%s/%s/%s", dirname, entry->d_name, "address");
221
if (n < 0 || n >= OBJNAMELEN)
222
a->error("File name too long");
223
file = fopen(namebuf, "r");
225
* Old versions of Linux had a fakephp which didn't have an 'address'
226
* file. There's no useful information to be gleaned from these
227
* devices, pretend they're not there.
232
if (!fgets(buf, sizeof(buf), file) || sscanf(buf, "%x:%x:%x", &dom, &bus, &dev) < 3)
233
a->warning("sysfs_fill_slots: Couldn't parse entry address %s", buf);
236
for (d = a->devices; d; d = d->next)
237
if (dom == d->domain && bus == d->bus && dev == d->dev && !d->phy_slot)
239
d->phy_slot = pci_malloc(a, strlen(entry->d_name) + 1);
240
strcpy(d->phy_slot, entry->d_name);
249
sysfs_fill_info(struct pci_dev *d, int flags)
251
if ((flags & PCI_FILL_PHYS_SLOT) && !(d->known_fields & PCI_FILL_PHYS_SLOT))
254
sysfs_fill_slots(d->access);
255
for (pd = d->access->devices; pd; pd = pd->next)
256
pd->known_fields |= PCI_FILL_PHYS_SLOT;
258
return pci_generic_fill_info(d, flags);
261
/* Intent of the sysfs_setup() caller */
264
SETUP_READ_CONFIG = 0,
265
SETUP_WRITE_CONFIG = 1,
270
sysfs_setup(struct pci_dev *d, int intent)
183
272
struct pci_access *a = d->access;
185
if (a->cached_dev != d || a->fd_rw < rw)
187
char namebuf[OBJNAMELEN];
273
char namebuf[OBJNAMELEN];
275
if (a->cached_dev != d || (intent == SETUP_WRITE_CONFIG && !a->fd_rw))
277
sysfs_flush_cache(a);
281
if (intent == SETUP_READ_VPD)
285
sysfs_obj_name(d, "vpd", namebuf);
286
a->fd_vpd = open(namebuf, O_RDONLY);
287
/* No warning on error; vpd may be absent or accessible only to root */
190
294
sysfs_obj_name(d, "config", namebuf);
191
a->fd_rw = a->writeable || rw;
295
a->fd_rw = a->writeable || intent == SETUP_WRITE_CONFIG;
192
296
a->fd = open(namebuf, a->fd_rw ? O_RDWR : O_RDONLY);
194
298
a->warning("Cannot open %s", namebuf);
343
#ifdef PCI_HAVE_DO_READ
345
/* pread() is not available and do_read() only works for a single fd, so we
346
* cannot implement read_vpd properly. */
347
static int sysfs_read_vpd(struct pci_dev *d, int pos, byte *buf, int len)
352
#else /* !PCI_HAVE_DO_READ */
354
static int sysfs_read_vpd(struct pci_dev *d, int pos, byte *buf, int len)
356
int fd = sysfs_setup(d, SETUP_READ_VPD);
361
res = pread(fd, buf, len, pos);
364
d->access->warning("sysfs_read_vpd: read failed: %s", strerror(errno));
372
#endif /* PCI_HAVE_DO_READ */
240
374
static void sysfs_cleanup_dev(struct pci_dev *d)
242
376
struct pci_access *a = d->access;
244
378
if (a->cached_dev == d)
246
a->cached_dev = NULL;
379
sysfs_flush_cache(a);
252
382
struct pci_methods pm_linux_sysfs = {