static int proc_write_node(struct file *file, const char __user * buf, unsigned long count, void *data) { struct pnp_bios_node *node; int boot = (long)data >> 8; u8 nodenum = (long)data; int ret = count; node = kzalloc(node_info.max_node_size, GFP_KERNEL); if (!node) return -ENOMEM; if (pnp_bios_get_dev_node(&nodenum, boot, node)) { ret = -EIO; goto out; } if (count != node->size - sizeof(struct pnp_bios_node)) { ret = -EINVAL; goto out; } if (copy_from_user(node->data, buf, count)) { ret = -EFAULT; goto out; } if (pnp_bios_set_dev_node(node->handle, boot, node) != 0) { ret = -EINVAL; goto out; } ret = count; out: kfree(node); return ret; }
int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data) { int status; status = __pnp_bios_set_dev_node(nodenum, boot, data); if (status) { pnpbios_print_status("set_dev_node", status); return status; } if (!boot) { /* Update devlist */ status = pnp_bios_get_dev_node(&nodenum, boot, data); if (status) return status; } return status; }
static int proc_read_node(char *buf, char **start, off_t pos, int count, int *eof, void *data) { struct pnp_bios_node *node; int boot = (long)data >> 8; u8 nodenum = (long)data; int len; node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); if (!node) return -ENOMEM; if (pnp_bios_get_dev_node(&nodenum, boot, node)) return -EIO; len = node->size - sizeof(struct pnp_bios_node); memcpy(buf, node->data, len); kfree(node); return len; }
static int proc_write_node(struct file *file, const char *buf, unsigned long count, void *data) { struct pnp_bios_node *node; int boot = (long)data >> 8; u8 num = (long)data; node = kmalloc(node_info.max_node_size, GFP_KERNEL); if (!node) return -ENOMEM; pnp_bios_get_dev_node(&num, boot, node); if (count != node->size - sizeof(struct pnp_bios_node)) return -EINVAL; memcpy(node->data, buf, count); if (pnp_bios_set_dev_node(node->handle, boot, node) != 0) return -EINVAL; kfree(node); return count; }
static int proc_read_devices(char *buf, char **start, off_t pos, int count, int *eof, void *data) { struct pnp_bios_node *node; u8 num; char *p = buf; node = kmalloc(node_info.max_node_size, GFP_KERNEL); if (!node) return -ENOMEM; for (num = 0; num != 0xff; ) { pnp_bios_get_dev_node(&num, 0, node); p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n", node->handle, node->eisa_id, node->type_code[0], node->type_code[1], node->type_code[2], node->flags); } kfree(node); return (p-buf); }
static int proc_read_devices(char *buf, char **start, off_t pos, int count, int *eof, void *data) { struct pnp_bios_node *node; u8 nodenum; char *p = buf; if (pos >= 0xff) return 0; node = kzalloc(node_info.max_node_size, GFP_KERNEL); if (!node) return -ENOMEM; for (nodenum = pos; nodenum < 0xff;) { u8 thisnodenum = nodenum; /* 26 = the number of characters per line sprintf'ed */ if ((p - buf + 26) > count) break; if (pnp_bios_get_dev_node(&nodenum, PNPMODE_DYNAMIC, node)) break; p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n", node->handle, node->eisa_id, node->type_code[0], node->type_code[1], node->type_code[2], node->flags); if (nodenum <= thisnodenum) { printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_read_devices:", (unsigned int)nodenum, (unsigned int)thisnodenum); *eof = 1; break; } } kfree(node); if (nodenum == 0xff) *eof = 1; *start = (char *)((off_t) nodenum - pos); return p - buf; }
void pnp_proc_init(void) { struct pnp_bios_node *node; struct proc_dir_entry *ent; char name[3]; u8 num; if (!pnp_bios_present()) return; if (pnp_bios_dev_node_info(&node_info) != 0) return; proc_pnp = proc_mkdir("pnp", proc_bus); if (!proc_pnp) return; proc_pnp_boot = proc_mkdir("boot", proc_pnp); if (!proc_pnp_boot) return; create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL); node = kmalloc(node_info.max_node_size, GFP_KERNEL); if (!node) return; for (num = 0; num != 0xff; ) { if (pnp_bios_get_dev_node(&num, 0, node) != 0) break; sprintf(name, "%02x", node->handle); ent = create_proc_entry(name, 0, proc_pnp); if (ent) { ent->read_proc = proc_read_node; ent->write_proc = proc_write_node; ent->data = (void *)(long)(node->handle); } ent = create_proc_entry(name, 0, proc_pnp_boot); if (ent) { ent->read_proc = proc_read_node; ent->write_proc = proc_write_node; ent->data = (void *)(long)(node->handle+0x100); } } kfree(node); }