root/drivers/pci/proc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. proc_bus_pci_lseek
  2. proc_bus_pci_read
  3. proc_bus_pci_write
  4. proc_bus_pci_ioctl
  5. proc_bus_pci_mmap
  6. proc_bus_pci_open
  7. proc_bus_pci_release
  8. pci_seq_start
  9. pci_seq_next
  10. pci_seq_stop
  11. show_device
  12. pci_proc_attach_device
  13. pci_proc_detach_device
  14. pci_proc_detach_bus
  15. pci_proc_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Procfs interface for the PCI bus
   4  *
   5  * Copyright (c) 1997--1999 Martin Mares <mj@ucw.cz>
   6  */
   7 
   8 #include <linux/init.h>
   9 #include <linux/pci.h>
  10 #include <linux/slab.h>
  11 #include <linux/module.h>
  12 #include <linux/proc_fs.h>
  13 #include <linux/seq_file.h>
  14 #include <linux/capability.h>
  15 #include <linux/uaccess.h>
  16 #include <linux/security.h>
  17 #include <asm/byteorder.h>
  18 #include "pci.h"
  19 
  20 static int proc_initialized;    /* = 0 */
  21 
  22 static loff_t proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
  23 {
  24         struct pci_dev *dev = PDE_DATA(file_inode(file));
  25         return fixed_size_llseek(file, off, whence, dev->cfg_size);
  26 }
  27 
  28 static ssize_t proc_bus_pci_read(struct file *file, char __user *buf,
  29                                  size_t nbytes, loff_t *ppos)
  30 {
  31         struct pci_dev *dev = PDE_DATA(file_inode(file));
  32         unsigned int pos = *ppos;
  33         unsigned int cnt, size;
  34 
  35         /*
  36          * Normal users can read only the standardized portion of the
  37          * configuration space as several chips lock up when trying to read
  38          * undefined locations (think of Intel PIIX4 as a typical example).
  39          */
  40 
  41         if (capable(CAP_SYS_ADMIN))
  42                 size = dev->cfg_size;
  43         else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
  44                 size = 128;
  45         else
  46                 size = 64;
  47 
  48         if (pos >= size)
  49                 return 0;
  50         if (nbytes >= size)
  51                 nbytes = size;
  52         if (pos + nbytes > size)
  53                 nbytes = size - pos;
  54         cnt = nbytes;
  55 
  56         if (!access_ok(buf, cnt))
  57                 return -EINVAL;
  58 
  59         pci_config_pm_runtime_get(dev);
  60 
  61         if ((pos & 1) && cnt) {
  62                 unsigned char val;
  63                 pci_user_read_config_byte(dev, pos, &val);
  64                 __put_user(val, buf);
  65                 buf++;
  66                 pos++;
  67                 cnt--;
  68         }
  69 
  70         if ((pos & 3) && cnt > 2) {
  71                 unsigned short val;
  72                 pci_user_read_config_word(dev, pos, &val);
  73                 __put_user(cpu_to_le16(val), (__le16 __user *) buf);
  74                 buf += 2;
  75                 pos += 2;
  76                 cnt -= 2;
  77         }
  78 
  79         while (cnt >= 4) {
  80                 unsigned int val;
  81                 pci_user_read_config_dword(dev, pos, &val);
  82                 __put_user(cpu_to_le32(val), (__le32 __user *) buf);
  83                 buf += 4;
  84                 pos += 4;
  85                 cnt -= 4;
  86         }
  87 
  88         if (cnt >= 2) {
  89                 unsigned short val;
  90                 pci_user_read_config_word(dev, pos, &val);
  91                 __put_user(cpu_to_le16(val), (__le16 __user *) buf);
  92                 buf += 2;
  93                 pos += 2;
  94                 cnt -= 2;
  95         }
  96 
  97         if (cnt) {
  98                 unsigned char val;
  99                 pci_user_read_config_byte(dev, pos, &val);
 100                 __put_user(val, buf);
 101                 buf++;
 102                 pos++;
 103                 cnt--;
 104         }
 105 
 106         pci_config_pm_runtime_put(dev);
 107 
 108         *ppos = pos;
 109         return nbytes;
 110 }
 111 
 112 static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf,
 113                                   size_t nbytes, loff_t *ppos)
 114 {
 115         struct inode *ino = file_inode(file);
 116         struct pci_dev *dev = PDE_DATA(ino);
 117         int pos = *ppos;
 118         int size = dev->cfg_size;
 119         int cnt, ret;
 120 
 121         ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
 122         if (ret)
 123                 return ret;
 124 
 125         if (pos >= size)
 126                 return 0;
 127         if (nbytes >= size)
 128                 nbytes = size;
 129         if (pos + nbytes > size)
 130                 nbytes = size - pos;
 131         cnt = nbytes;
 132 
 133         if (!access_ok(buf, cnt))
 134                 return -EINVAL;
 135 
 136         pci_config_pm_runtime_get(dev);
 137 
 138         if ((pos & 1) && cnt) {
 139                 unsigned char val;
 140                 __get_user(val, buf);
 141                 pci_user_write_config_byte(dev, pos, val);
 142                 buf++;
 143                 pos++;
 144                 cnt--;
 145         }
 146 
 147         if ((pos & 3) && cnt > 2) {
 148                 __le16 val;
 149                 __get_user(val, (__le16 __user *) buf);
 150                 pci_user_write_config_word(dev, pos, le16_to_cpu(val));
 151                 buf += 2;
 152                 pos += 2;
 153                 cnt -= 2;
 154         }
 155 
 156         while (cnt >= 4) {
 157                 __le32 val;
 158                 __get_user(val, (__le32 __user *) buf);
 159                 pci_user_write_config_dword(dev, pos, le32_to_cpu(val));
 160                 buf += 4;
 161                 pos += 4;
 162                 cnt -= 4;
 163         }
 164 
 165         if (cnt >= 2) {
 166                 __le16 val;
 167                 __get_user(val, (__le16 __user *) buf);
 168                 pci_user_write_config_word(dev, pos, le16_to_cpu(val));
 169                 buf += 2;
 170                 pos += 2;
 171                 cnt -= 2;
 172         }
 173 
 174         if (cnt) {
 175                 unsigned char val;
 176                 __get_user(val, buf);
 177                 pci_user_write_config_byte(dev, pos, val);
 178                 buf++;
 179                 pos++;
 180                 cnt--;
 181         }
 182 
 183         pci_config_pm_runtime_put(dev);
 184 
 185         *ppos = pos;
 186         i_size_write(ino, dev->cfg_size);
 187         return nbytes;
 188 }
 189 
 190 struct pci_filp_private {
 191         enum pci_mmap_state mmap_state;
 192         int write_combine;
 193 };
 194 
 195 static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
 196                                unsigned long arg)
 197 {
 198         struct pci_dev *dev = PDE_DATA(file_inode(file));
 199 #ifdef HAVE_PCI_MMAP
 200         struct pci_filp_private *fpriv = file->private_data;
 201 #endif /* HAVE_PCI_MMAP */
 202         int ret = 0;
 203 
 204         ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
 205         if (ret)
 206                 return ret;
 207 
 208         switch (cmd) {
 209         case PCIIOC_CONTROLLER:
 210                 ret = pci_domain_nr(dev->bus);
 211                 break;
 212 
 213 #ifdef HAVE_PCI_MMAP
 214         case PCIIOC_MMAP_IS_IO:
 215                 if (!arch_can_pci_mmap_io())
 216                         return -EINVAL;
 217                 fpriv->mmap_state = pci_mmap_io;
 218                 break;
 219 
 220         case PCIIOC_MMAP_IS_MEM:
 221                 fpriv->mmap_state = pci_mmap_mem;
 222                 break;
 223 
 224         case PCIIOC_WRITE_COMBINE:
 225                 if (arch_can_pci_mmap_wc()) {
 226                         if (arg)
 227                                 fpriv->write_combine = 1;
 228                         else
 229                                 fpriv->write_combine = 0;
 230                         break;
 231                 }
 232                 /* If arch decided it can't, fall through... */
 233 #endif /* HAVE_PCI_MMAP */
 234                 /* fall through */
 235         default:
 236                 ret = -EINVAL;
 237                 break;
 238         }
 239 
 240         return ret;
 241 }
 242 
 243 #ifdef HAVE_PCI_MMAP
 244 static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
 245 {
 246         struct pci_dev *dev = PDE_DATA(file_inode(file));
 247         struct pci_filp_private *fpriv = file->private_data;
 248         int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM;
 249 
 250         if (!capable(CAP_SYS_RAWIO) ||
 251             security_locked_down(LOCKDOWN_PCI_ACCESS))
 252                 return -EPERM;
 253 
 254         if (fpriv->mmap_state == pci_mmap_io) {
 255                 if (!arch_can_pci_mmap_io())
 256                         return -EINVAL;
 257                 res_bit = IORESOURCE_IO;
 258         }
 259 
 260         /* Make sure the caller is mapping a real resource for this device */
 261         for (i = 0; i < PCI_ROM_RESOURCE; i++) {
 262                 if (dev->resource[i].flags & res_bit &&
 263                     pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
 264                         break;
 265         }
 266 
 267         if (i >= PCI_ROM_RESOURCE)
 268                 return -ENODEV;
 269 
 270         if (fpriv->mmap_state == pci_mmap_mem &&
 271             fpriv->write_combine) {
 272                 if (dev->resource[i].flags & IORESOURCE_PREFETCH)
 273                         write_combine = 1;
 274                 else
 275                         return -EINVAL;
 276         }
 277         ret = pci_mmap_page_range(dev, i, vma,
 278                                   fpriv->mmap_state, write_combine);
 279         if (ret < 0)
 280                 return ret;
 281 
 282         return 0;
 283 }
 284 
 285 static int proc_bus_pci_open(struct inode *inode, struct file *file)
 286 {
 287         struct pci_filp_private *fpriv = kmalloc(sizeof(*fpriv), GFP_KERNEL);
 288 
 289         if (!fpriv)
 290                 return -ENOMEM;
 291 
 292         fpriv->mmap_state = pci_mmap_io;
 293         fpriv->write_combine = 0;
 294 
 295         file->private_data = fpriv;
 296 
 297         return 0;
 298 }
 299 
 300 static int proc_bus_pci_release(struct inode *inode, struct file *file)
 301 {
 302         kfree(file->private_data);
 303         file->private_data = NULL;
 304 
 305         return 0;
 306 }
 307 #endif /* HAVE_PCI_MMAP */
 308 
 309 static const struct file_operations proc_bus_pci_operations = {
 310         .owner          = THIS_MODULE,
 311         .llseek         = proc_bus_pci_lseek,
 312         .read           = proc_bus_pci_read,
 313         .write          = proc_bus_pci_write,
 314         .unlocked_ioctl = proc_bus_pci_ioctl,
 315         .compat_ioctl   = proc_bus_pci_ioctl,
 316 #ifdef HAVE_PCI_MMAP
 317         .open           = proc_bus_pci_open,
 318         .release        = proc_bus_pci_release,
 319         .mmap           = proc_bus_pci_mmap,
 320 #ifdef HAVE_ARCH_PCI_GET_UNMAPPED_AREA
 321         .get_unmapped_area = get_pci_unmapped_area,
 322 #endif /* HAVE_ARCH_PCI_GET_UNMAPPED_AREA */
 323 #endif /* HAVE_PCI_MMAP */
 324 };
 325 
 326 /* iterator */
 327 static void *pci_seq_start(struct seq_file *m, loff_t *pos)
 328 {
 329         struct pci_dev *dev = NULL;
 330         loff_t n = *pos;
 331 
 332         for_each_pci_dev(dev) {
 333                 if (!n--)
 334                         break;
 335         }
 336         return dev;
 337 }
 338 
 339 static void *pci_seq_next(struct seq_file *m, void *v, loff_t *pos)
 340 {
 341         struct pci_dev *dev = v;
 342 
 343         (*pos)++;
 344         dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
 345         return dev;
 346 }
 347 
 348 static void pci_seq_stop(struct seq_file *m, void *v)
 349 {
 350         if (v) {
 351                 struct pci_dev *dev = v;
 352                 pci_dev_put(dev);
 353         }
 354 }
 355 
 356 static int show_device(struct seq_file *m, void *v)
 357 {
 358         const struct pci_dev *dev = v;
 359         const struct pci_driver *drv;
 360         int i;
 361 
 362         if (dev == NULL)
 363                 return 0;
 364 
 365         drv = pci_dev_driver(dev);
 366         seq_printf(m, "%02x%02x\t%04x%04x\t%x",
 367                         dev->bus->number,
 368                         dev->devfn,
 369                         dev->vendor,
 370                         dev->device,
 371                         dev->irq);
 372 
 373         /* only print standard and ROM resources to preserve compatibility */
 374         for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
 375                 resource_size_t start, end;
 376                 pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
 377                 seq_printf(m, "\t%16llx",
 378                         (unsigned long long)(start |
 379                         (dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
 380         }
 381         for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
 382                 resource_size_t start, end;
 383                 pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
 384                 seq_printf(m, "\t%16llx",
 385                         dev->resource[i].start < dev->resource[i].end ?
 386                         (unsigned long long)(end - start) + 1 : 0);
 387         }
 388         seq_putc(m, '\t');
 389         if (drv)
 390                 seq_puts(m, drv->name);
 391         seq_putc(m, '\n');
 392         return 0;
 393 }
 394 
 395 static const struct seq_operations proc_bus_pci_devices_op = {
 396         .start  = pci_seq_start,
 397         .next   = pci_seq_next,
 398         .stop   = pci_seq_stop,
 399         .show   = show_device
 400 };
 401 
 402 static struct proc_dir_entry *proc_bus_pci_dir;
 403 
 404 int pci_proc_attach_device(struct pci_dev *dev)
 405 {
 406         struct pci_bus *bus = dev->bus;
 407         struct proc_dir_entry *e;
 408         char name[16];
 409 
 410         if (!proc_initialized)
 411                 return -EACCES;
 412 
 413         if (!bus->procdir) {
 414                 if (pci_proc_domain(bus)) {
 415                         sprintf(name, "%04x:%02x", pci_domain_nr(bus),
 416                                         bus->number);
 417                 } else {
 418                         sprintf(name, "%02x", bus->number);
 419                 }
 420                 bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
 421                 if (!bus->procdir)
 422                         return -ENOMEM;
 423         }
 424 
 425         sprintf(name, "%02x.%x", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
 426         e = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, bus->procdir,
 427                              &proc_bus_pci_operations, dev);
 428         if (!e)
 429                 return -ENOMEM;
 430         proc_set_size(e, dev->cfg_size);
 431         dev->procent = e;
 432 
 433         return 0;
 434 }
 435 
 436 int pci_proc_detach_device(struct pci_dev *dev)
 437 {
 438         proc_remove(dev->procent);
 439         dev->procent = NULL;
 440         return 0;
 441 }
 442 
 443 int pci_proc_detach_bus(struct pci_bus *bus)
 444 {
 445         proc_remove(bus->procdir);
 446         return 0;
 447 }
 448 
 449 static int __init pci_proc_init(void)
 450 {
 451         struct pci_dev *dev = NULL;
 452         proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
 453         proc_create_seq("devices", 0, proc_bus_pci_dir,
 454                     &proc_bus_pci_devices_op);
 455         proc_initialized = 1;
 456         for_each_pci_dev(dev)
 457                 pci_proc_attach_device(dev);
 458 
 459         return 0;
 460 }
 461 device_initcall(pci_proc_init);

/* [<][>][^][v][top][bottom][index][help] */