18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * ISA Plug & Play support 48c2ecf20Sopenharmony_ci * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/module.h> 88c2ecf20Sopenharmony_ci#include <linux/isapnp.h> 98c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 108c2ecf20Sopenharmony_ci#include <linux/init.h> 118c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ciextern struct pnp_protocol isapnp_protocol; 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistatic struct proc_dir_entry *isapnp_proc_bus_dir = NULL; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci return fixed_size_llseek(file, off, whence, 256); 208c2ecf20Sopenharmony_ci} 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf, 238c2ecf20Sopenharmony_ci size_t nbytes, loff_t * ppos) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci struct pnp_dev *dev = PDE_DATA(file_inode(file)); 268c2ecf20Sopenharmony_ci int pos = *ppos; 278c2ecf20Sopenharmony_ci int cnt, size = 256; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci if (pos >= size) 308c2ecf20Sopenharmony_ci return 0; 318c2ecf20Sopenharmony_ci if (nbytes >= size) 328c2ecf20Sopenharmony_ci nbytes = size; 338c2ecf20Sopenharmony_ci if (pos + nbytes > size) 348c2ecf20Sopenharmony_ci nbytes = size - pos; 358c2ecf20Sopenharmony_ci cnt = nbytes; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (!access_ok(buf, cnt)) 388c2ecf20Sopenharmony_ci return -EINVAL; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci isapnp_cfg_begin(dev->card->number, dev->number); 418c2ecf20Sopenharmony_ci for (; pos < 256 && cnt > 0; pos++, buf++, cnt--) { 428c2ecf20Sopenharmony_ci unsigned char val; 438c2ecf20Sopenharmony_ci val = isapnp_read_byte(pos); 448c2ecf20Sopenharmony_ci __put_user(val, buf); 458c2ecf20Sopenharmony_ci } 468c2ecf20Sopenharmony_ci isapnp_cfg_end(); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci *ppos = pos; 498c2ecf20Sopenharmony_ci return nbytes; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistatic const struct proc_ops isapnp_proc_bus_proc_ops = { 538c2ecf20Sopenharmony_ci .proc_lseek = isapnp_proc_bus_lseek, 548c2ecf20Sopenharmony_ci .proc_read = isapnp_proc_bus_read, 558c2ecf20Sopenharmony_ci}; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic int isapnp_proc_attach_device(struct pnp_dev *dev) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci struct pnp_card *bus = dev->card; 608c2ecf20Sopenharmony_ci struct proc_dir_entry *de, *e; 618c2ecf20Sopenharmony_ci char name[16]; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci if (!(de = bus->procdir)) { 648c2ecf20Sopenharmony_ci sprintf(name, "%02x", bus->number); 658c2ecf20Sopenharmony_ci de = bus->procdir = proc_mkdir(name, isapnp_proc_bus_dir); 668c2ecf20Sopenharmony_ci if (!de) 678c2ecf20Sopenharmony_ci return -ENOMEM; 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci sprintf(name, "%02x", dev->number); 708c2ecf20Sopenharmony_ci e = dev->procent = proc_create_data(name, S_IFREG | S_IRUGO, de, 718c2ecf20Sopenharmony_ci &isapnp_proc_bus_proc_ops, dev); 728c2ecf20Sopenharmony_ci if (!e) 738c2ecf20Sopenharmony_ci return -ENOMEM; 748c2ecf20Sopenharmony_ci proc_set_size(e, 256); 758c2ecf20Sopenharmony_ci return 0; 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ciint __init isapnp_proc_init(void) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci struct pnp_dev *dev; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci isapnp_proc_bus_dir = proc_mkdir("bus/isapnp", NULL); 838c2ecf20Sopenharmony_ci protocol_for_each_dev(&isapnp_protocol, dev) { 848c2ecf20Sopenharmony_ci isapnp_proc_attach_device(dev); 858c2ecf20Sopenharmony_ci } 868c2ecf20Sopenharmony_ci return 0; 878c2ecf20Sopenharmony_ci} 88