diff options
Diffstat (limited to 'drivers/sbus/char')
-rw-r--r-- | drivers/sbus/char/aurora.c | 12 | ||||
-rw-r--r-- | drivers/sbus/char/bbc_envctrl.c | 4 | ||||
-rw-r--r-- | drivers/sbus/char/bbc_i2c.c | 6 | ||||
-rw-r--r-- | drivers/sbus/char/bpp.c | 9 | ||||
-rw-r--r-- | drivers/sbus/char/cpwatchdog.c | 8 | ||||
-rw-r--r-- | drivers/sbus/char/display7seg.c | 2 | ||||
-rw-r--r-- | drivers/sbus/char/envctrl.c | 72 | ||||
-rw-r--r-- | drivers/sbus/char/flash.c | 18 | ||||
-rw-r--r-- | drivers/sbus/char/openprom.c | 594 | ||||
-rw-r--r-- | drivers/sbus/char/riowatchdog.c | 4 | ||||
-rw-r--r-- | drivers/sbus/char/uctrl.c | 2 | ||||
-rw-r--r-- | drivers/sbus/char/vfc.h | 2 | ||||
-rw-r--r-- | drivers/sbus/char/vfc_dev.c | 9 |
13 files changed, 398 insertions, 344 deletions
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c index 015db40ad8a..4fdb2c93221 100644 --- a/drivers/sbus/char/aurora.c +++ b/drivers/sbus/char/aurora.c @@ -337,19 +337,19 @@ static int aurora_probe(void) printk("intr pri %d\n", grrr); #endif if ((bp->irq=irqs[bn]) && valid_irq(bp->irq) && - !request_irq(bp->irq|0x30, aurora_interrupt, SA_SHIRQ, "sio16", bp)) { + !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) { free_irq(bp->irq|0x30, bp); } else if ((bp->irq=prom_getint(sdev->prom_node, "bintr")) && valid_irq(bp->irq) && - !request_irq(bp->irq|0x30, aurora_interrupt, SA_SHIRQ, "sio16", bp)) { + !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) { free_irq(bp->irq|0x30, bp); } else if ((bp->irq=prom_getint(sdev->prom_node, "intr")) && valid_irq(bp->irq) && - !request_irq(bp->irq|0x30, aurora_interrupt, SA_SHIRQ, "sio16", bp)) { + !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) { free_irq(bp->irq|0x30, bp); } else for(grrr=0;grrr<TYPE_1_IRQS;grrr++) { - if ((bp->irq=type_1_irq[grrr])&&!request_irq(bp->irq|0x30, aurora_interrupt, SA_SHIRQ, "sio16", bp)) { + if ((bp->irq=type_1_irq[grrr])&&!request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) { free_irq(bp->irq|0x30, bp); break; } else { @@ -909,14 +909,14 @@ static int aurora_setup_board(struct Aurora_board * bp) #ifdef AURORA_ALLIRQ int i; for (i = 0; i < AURORA_ALLIRQ; i++) { - error = request_irq(allirq[i]|0x30, aurora_interrupt, SA_SHIRQ, + error = request_irq(allirq[i]|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp); if (error) printk(KERN_ERR "IRQ%d request error %d\n", allirq[i], error); } #else - error = request_irq(bp->irq|0x30, aurora_interrupt, SA_SHIRQ, + error = request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp); if (error) { printk(KERN_ERR "IRQ request error %d\n", error); diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index d89f83f769f..1cc706e1111 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c @@ -575,9 +575,9 @@ int bbc_envctrl_init(void) int devidx = 0; while ((echild = bbc_i2c_getdev(devidx++)) != NULL) { - if (!strcmp(echild->prom_name, "temperature")) + if (!strcmp(echild->prom_node->name, "temperature")) attach_one_temp(echild, temp_index++); - if (!strcmp(echild->prom_name, "fan-control")) + if (!strcmp(echild->prom_node->name, "fan-control")) attach_one_fan(echild, fan_index++); } if (temp_index != 0 && fan_index != 0) { diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 3e156e005f2..7186235594f 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -377,7 +377,7 @@ static int __init attach_one_i2c(struct linux_ebus_device *edev, int index) bp->waiting = 0; init_waitqueue_head(&bp->wq); if (request_irq(edev->irqs[0], bbc_i2c_interrupt, - SA_SHIRQ, "bbc_i2c", bp)) + IRQF_SHARED, "bbc_i2c", bp)) goto fail; bp->index = index; @@ -423,7 +423,7 @@ static int __init bbc_present(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "bbc")) + if (!strcmp(edev->prom_node->name, "bbc")) return 1; } } @@ -446,7 +446,7 @@ static int __init bbc_i2c_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "i2c")) { + if (!strcmp(edev->prom_node->name, "i2c")) { if (!attach_one_i2c(edev, index)) index++; } diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index ccb20a6f5f3..385f4f76831 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c @@ -20,7 +20,6 @@ #include <linux/timer.h> #include <linux/ioport.h> #include <linux/major.h> -#include <linux/devfs_fs_kernel.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -1031,11 +1030,6 @@ static int __init bpp_init(void) instances[idx].opened = 0; probeLptPort(idx); } - devfs_mk_dir("bpp"); - for (idx = 0; idx < BPP_NO; idx++) { - devfs_mk_cdev(MKDEV(BPP_MAJOR, idx), - S_IFCHR | S_IRUSR | S_IWUSR, "bpp/%d", idx); - } return 0; } @@ -1044,9 +1038,6 @@ static void __exit bpp_cleanup(void) { unsigned idx; - for (idx = 0; idx < BPP_NO; idx++) - devfs_remove("bpp/%d", idx); - devfs_remove("bpp"); unregister_chrdev(BPP_MAJOR, dev_name); for (idx = 0; idx < BPP_NO; idx++) { diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c index fd2cc7782f7..836a58bb030 100644 --- a/drivers/sbus/char/cpwatchdog.c +++ b/drivers/sbus/char/cpwatchdog.c @@ -301,11 +301,11 @@ static int wd_open(struct inode *inode, struct file *f) { if (request_irq(wd_dev.irq, &wd_interrupt, - SA_SHIRQ, + IRQF_SHARED, WD_OBPNAME, (void *)wd_dev.regs)) { - printk("%s: Cannot register IRQ %s\n", - WD_OBPNAME, __irq_itoa(wd_dev.irq)); + printk("%s: Cannot register IRQ %d\n", + WD_OBPNAME, wd_dev.irq); return(-EBUSY); } wd_dev.initialized = 1; @@ -755,7 +755,7 @@ static int __init wd_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, WD_OBPNAME)) + if (!strcmp(edev->ofdev.node->name, WD_OBPNAME)) goto ebus_done; } } diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index c3a51d1fae5..d92bc8827a9 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -184,7 +184,7 @@ static int __init d7s_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, D7S_OBPNAME)) + if (!strcmp(edev->prom_node->name, D7S_OBPNAME)) goto ebus_done; } } diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index 19e8eddf887..063e676a3ac 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -22,7 +22,6 @@ #define __KERNEL_SYSCALLS__ static int errno; -#include <linux/config.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/kthread.h> @@ -768,16 +767,14 @@ static void envctrl_set_mon(struct i2c_child_t *pchild, * decoding tables, monitor type, optional properties. * Return: None. */ -static void envctrl_init_adc(struct i2c_child_t *pchild, int node) +static void envctrl_init_adc(struct i2c_child_t *pchild, struct device_node *dp) { - char chnls_desc[CHANNEL_DESC_SZ]; int i = 0, len; - char *pos = chnls_desc; + char *pos; + unsigned int *pval; /* Firmware describe channels into a stream separated by a '\0'. */ - len = prom_getproperty(node, "channels-description", chnls_desc, - CHANNEL_DESC_SZ); - chnls_desc[CHANNEL_DESC_SZ - 1] = '\0'; + pos = of_get_property(dp, "channels-description", &len); while (len > 0) { int l = strlen(pos) + 1; @@ -787,10 +784,13 @@ static void envctrl_init_adc(struct i2c_child_t *pchild, int node) } /* Get optional properties. */ - len = prom_getproperty(node, "warning-temp", (char *)&warning_temperature, - sizeof(warning_temperature)); - len = prom_getproperty(node, "shutdown-temp", (char *)&shutdown_temperature, - sizeof(shutdown_temperature)); + pval = of_get_property(dp, "warning-temp", NULL); + if (pval) + warning_temperature = *pval; + + pval = of_get_property(dp, "shutdown-temp", NULL); + if (pval) + shutdown_temperature = *pval; } /* Function Description: Initialize child device monitoring fan status. @@ -864,21 +864,18 @@ static void envctrl_init_voltage_status(struct i2c_child_t *pchild) static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, struct i2c_child_t *pchild) { - int node, len, i, tbls_size = 0; - - node = edev_child->prom_node; + int len, i, tbls_size = 0; + struct device_node *dp = edev_child->prom_node; + void *pval; /* Get device address. */ - len = prom_getproperty(node, "reg", - (char *) &(pchild->addr), - sizeof(pchild->addr)); + pval = of_get_property(dp, "reg", &len); + memcpy(&pchild->addr, pval, len); /* Get tables property. Read firmware temperature tables. */ - len = prom_getproperty(node, "translation", - (char *) pchild->tblprop_array, - (PCF8584_MAX_CHANNELS * - sizeof(struct pcf8584_tblprop))); - if (len > 0) { + pval = of_get_property(dp, "translation", &len); + if (pval && len > 0) { + memcpy(pchild->tblprop_array, pval, len); pchild->total_tbls = len / sizeof(struct pcf8584_tblprop); for (i = 0; i < pchild->total_tbls; i++) { if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) { @@ -891,12 +888,12 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, printk("envctrl: Failed to allocate table.\n"); return; } - len = prom_getproperty(node, "tables", - (char *) pchild->tables, tbls_size); - if (len <= 0) { + pval = of_get_property(dp, "tables", &len); + if (!pval || len <= 0) { printk("envctrl: Failed to get table.\n"); return; } + memcpy(pchild->tables, pval, len); } /* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04) @@ -907,12 +904,11 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, * 'NULL' monitor type. */ if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) { + struct device_node *root_node; int len; - char prop[56]; - len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop)); - if (0 < len && (0 == strncmp(prop, "SUNW,UltraSPARC-IIi-cEngine", len))) - { + root_node = of_find_node_by_path("/"); + if (!strcmp(root_node->name, "SUNW,UltraSPARC-IIi-cEngine")) { for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) { pchild->mon_type[len] = ENVCTRL_NOMON; } @@ -921,16 +917,14 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, } /* Get the monitor channels. */ - len = prom_getproperty(node, "channels-in-use", - (char *) pchild->chnl_array, - (PCF8584_MAX_CHANNELS * - sizeof(struct pcf8584_channel))); + pval = of_get_property(dp, "channels-in-use", &len); + memcpy(pchild->chnl_array, pval, len); pchild->total_chnls = len / sizeof(struct pcf8584_channel); for (i = 0; i < pchild->total_chnls; i++) { switch (pchild->chnl_array[i].type) { case PCF8584_TEMP_TYPE: - envctrl_init_adc(pchild, node); + envctrl_init_adc(pchild, dp); break; case PCF8584_GLOBALADDR_TYPE: @@ -945,7 +939,7 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, case PCF8584_VOLTAGE_TYPE: if (pchild->i2ctype == I2C_ADC) { - envctrl_init_adc(pchild,node); + envctrl_init_adc(pchild,dp); } else { envctrl_init_voltage_status(pchild); } @@ -1046,7 +1040,7 @@ static int __init envctrl_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "bbc")) { + if (!strcmp(edev->prom_node->name, "bbc")) { /* If we find a boot-bus controller node, * then this envctrl driver is not for us. */ @@ -1060,14 +1054,14 @@ static int __init envctrl_init(void) */ for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "i2c")) { + if (!strcmp(edev->prom_node->name, "i2c")) { i2c = ioremap(edev->resource[0].start, 0x2); for_each_edevchild(edev, edev_child) { - if (!strcmp("gpio", edev_child->prom_name)) { + if (!strcmp("gpio", edev_child->prom_node->name)) { i2c_childlist[i].i2ctype = I2C_GPIO; envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); } - if (!strcmp("adc", edev_child->prom_name)) { + if (!strcmp("adc", edev_child->prom_node->name)) { i2c_childlist[i].i2ctype = I2C_ADC; envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); } diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 2beb3dded08..fa2418f7ad3 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -4,7 +4,6 @@ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> @@ -71,7 +70,6 @@ flash_mmap(struct file *file, struct vm_area_struct *vma) if (vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)) > size) size = vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)); - vma->vm_flags |= (VM_SHM | VM_LOCKED); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) @@ -192,9 +190,11 @@ static int __init flash_init(void) } if (!sdev) { #ifdef CONFIG_PCI + struct linux_prom_registers *ebus_regs; + for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "flashprom")) + if (!strcmp(edev->prom_node->name, "flashprom")) goto ebus_done; } } @@ -202,23 +202,23 @@ static int __init flash_init(void) if (!edev) return -ENODEV; - len = prom_getproperty(edev->prom_node, "reg", (void *)regs, sizeof(regs)); - if ((len % sizeof(regs[0])) != 0) { + ebus_regs = of_get_property(edev->prom_node, "reg", &len); + if (!ebus_regs || (len % sizeof(regs[0])) != 0) { printk("flash: Strange reg property size %d\n", len); return -ENODEV; } - nregs = len / sizeof(regs[0]); + nregs = len / sizeof(ebus_regs[0]); flash.read_base = edev->resource[0].start; - flash.read_size = regs[0].reg_size; + flash.read_size = ebus_regs[0].reg_size; if (nregs == 1) { flash.write_base = edev->resource[0].start; - flash.write_size = regs[0].reg_size; + flash.write_size = ebus_regs[0].reg_size; } else if (nregs == 2) { flash.write_base = edev->resource[1].start; - flash.write_size = regs[1].reg_size; + flash.write_size = ebus_regs[1].reg_size; } else { printk("flash: Strange number of regs %d\n", nregs); return -ENODEV; diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index 239e108b8ed..293bb2fdb1d 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -29,9 +29,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define PROMLIB_INTERNAL - -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -39,10 +36,10 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/miscdevice.h> -#include <linux/smp_lock.h> #include <linux/init.h> #include <linux/fs.h> #include <asm/oplib.h> +#include <asm/prom.h> #include <asm/system.h> #include <asm/uaccess.h> #include <asm/openpromio.h> @@ -51,15 +48,20 @@ #include <asm/pbm.h> #endif +MODULE_AUTHOR("Thomas K. Dyas (tdyas@noc.rutgers.edu) and Eddie C. Dost (ecd@skynet.be)"); +MODULE_DESCRIPTION("OPENPROM Configuration Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); + /* Private data kept by the driver for each descriptor. */ typedef struct openprom_private_data { - int current_node; /* Current node for SunOS ioctls. */ - int lastnode; /* Last valid node used by BSD ioctls. */ + struct device_node *current_node; /* Current node for SunOS ioctls. */ + struct device_node *lastnode; /* Last valid node used by BSD ioctls. */ } DATA; /* ID of the PROM node containing all of the EEPROM options. */ -static int options_node = 0; +static struct device_node *options_node; /* * Copy an openpromio structure into kernel space from user space. @@ -87,9 +89,8 @@ static int copyin(struct openpromio __user *info, struct openpromio **opp_p) if (bufsize > OPROMMAXPARAM) bufsize = OPROMMAXPARAM; - if (!(*opp_p = kmalloc(sizeof(int) + bufsize + 1, GFP_KERNEL))) + if (!(*opp_p = kzalloc(sizeof(int) + bufsize + 1, GFP_KERNEL))) return -ENOMEM; - memset(*opp_p, 0, sizeof(int) + bufsize + 1); if (copy_from_user(&(*opp_p)->oprom_array, &info->oprom_array, bufsize)) { @@ -107,10 +108,9 @@ static int getstrings(struct openpromio __user *info, struct openpromio **opp_p) if (!info || !opp_p) return -EFAULT; - if (!(*opp_p = kmalloc(sizeof(int) + OPROMMAXPARAM + 1, GFP_KERNEL))) + if (!(*opp_p = kzalloc(sizeof(int) + OPROMMAXPARAM + 1, GFP_KERNEL))) return -ENOMEM; - memset(*opp_p, 0, sizeof(int) + OPROMMAXPARAM + 1); (*opp_p)->oprom_size = 0; n = bufsize = 0; @@ -140,16 +140,164 @@ static int copyout(void __user *info, struct openpromio *opp, int len) return 0; } +static int opromgetprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize) +{ + void *pval; + int len; + + pval = of_get_property(dp, op->oprom_array, &len); + if (!pval || len <= 0 || len > bufsize) + return copyout(argp, op, sizeof(int)); + + memcpy(op->oprom_array, pval, len); + op->oprom_array[len] = '\0'; + op->oprom_size = len; + + return copyout(argp, op, sizeof(int) + bufsize); +} + +static int opromnxtprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize) +{ + struct property *prop; + int len; + + if (op->oprom_array[0] == '\0') { + prop = dp->properties; + if (!prop) + return copyout(argp, op, sizeof(int)); + len = strlen(prop->name); + } else { + prop = of_find_property(dp, op->oprom_array, NULL); + + if (!prop || + !prop->next || + (len = strlen(prop->next->name)) + 1 > bufsize) + return copyout(argp, op, sizeof(int)); + + prop = prop->next; + } + + memcpy(op->oprom_array, prop->name, len); + op->oprom_array[len] = '\0'; + op->oprom_size = ++len; + + return copyout(argp, op, sizeof(int) + bufsize); +} + +static int opromsetopt(struct device_node *dp, struct openpromio *op, int bufsize) +{ + char *buf = op->oprom_array + strlen(op->oprom_array) + 1; + int len = op->oprom_array + bufsize - buf; + + return of_set_property(options_node, op->oprom_array, buf, len); +} + +static int opromnext(void __user *argp, unsigned int cmd, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) +{ + phandle ph; + + BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); + + if (bufsize < sizeof(phandle)) + return -EINVAL; + + ph = *((int *) op->oprom_array); + if (ph) { + dp = of_find_node_by_phandle(ph); + if (!dp) + return -EINVAL; + + switch (cmd) { + case OPROMNEXT: + dp = dp->sibling; + break; + + case OPROMCHILD: + dp = dp->child; + break; + + case OPROMSETCUR: + default: + break; + }; + } else { + /* Sibling of node zero is the root node. */ + if (cmd != OPROMNEXT) + return -EINVAL; + + dp = of_find_node_by_path("/"); + } + + ph = 0; + if (dp) + ph = dp->node; + + data->current_node = dp; + *((int *) op->oprom_array) = ph; + op->oprom_size = sizeof(phandle); + + return copyout(argp, op, bufsize + sizeof(int)); +} + +static int oprompci2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) +{ + int err = -EINVAL; + + if (bufsize >= 2*sizeof(int)) { +#ifdef CONFIG_PCI + struct pci_dev *pdev; + struct pcidev_cookie *pcp; + pdev = pci_find_slot (((int *) op->oprom_array)[0], + ((int *) op->oprom_array)[1]); + + pcp = pdev->sysdata; + if (pcp != NULL) { + dp = pcp->prom_node; + data->current_node = dp; + *((int *)op->oprom_array) = dp->node; + op->oprom_size = sizeof(int); + err = copyout(argp, op, bufsize + sizeof(int)); + } +#endif + } + + return err; +} + +static int oprompath2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) +{ + dp = of_find_node_by_path(op->oprom_array); + data->current_node = dp; + *((int *)op->oprom_array) = dp->node; + op->oprom_size = sizeof(int); + + return copyout(argp, op, bufsize + sizeof(int)); +} + +static int opromgetbootargs(void __user *argp, struct openpromio *op, int bufsize) +{ + char *buf = saved_command_line; + int len = strlen(buf); + + if (len > bufsize) + return -EINVAL; + + strcpy(op->oprom_array, buf); + op->oprom_size = len; + + return copyout(argp, op, bufsize + sizeof(int)); +} + /* * SunOS and Solaris /dev/openprom ioctl calls. */ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg, int node) + unsigned int cmd, unsigned long arg, + struct device_node *dp) { - DATA *data = (DATA *) file->private_data; - char buffer[OPROMMAXPARAM+1], *buf; + DATA *data = file->private_data; struct openpromio *opp; - int bufsize, len, error = 0; + int bufsize, error = 0; static int cnt; void __user *argp = (void __user *)arg; @@ -164,119 +312,35 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, switch (cmd) { case OPROMGETOPT: case OPROMGETPROP: - len = prom_getproplen(node, opp->oprom_array); - - if (len <= 0 || len > bufsize) { - error = copyout(argp, opp, sizeof(int)); - break; - } - - len = prom_getproperty(node, opp->oprom_array, buffer, bufsize); - - memcpy(opp->oprom_array, buffer, len); - opp->oprom_array[len] = '\0'; - opp->oprom_size = len; - - error = copyout(argp, opp, sizeof(int) + bufsize); + error = opromgetprop(argp, dp, opp, bufsize); break; case OPROMNXTOPT: case OPROMNXTPROP: - buf = prom_nextprop(node, opp->oprom_array, buffer); - - len = strlen(buf); - if (len == 0 || len + 1 > bufsize) { - error = copyout(argp, opp, sizeof(int)); - break; - } - - memcpy(opp->oprom_array, buf, len); - opp->oprom_array[len] = '\0'; - opp->oprom_size = ++len; - - error = copyout(argp, opp, sizeof(int) + bufsize); + error = opromnxtprop(argp, dp, opp, bufsize); break; case OPROMSETOPT: case OPROMSETOPT2: - buf = opp->oprom_array + strlen(opp->oprom_array) + 1; - len = opp->oprom_array + bufsize - buf; - - error = prom_setprop(options_node, opp->oprom_array, - buf, len); - - if (error < 0) - error = -EINVAL; + error = opromsetopt(dp, opp, bufsize); break; case OPROMNEXT: case OPROMCHILD: case OPROMSETCUR: - if (bufsize < sizeof(int)) { - error = -EINVAL; - break; - } - - node = *((int *) opp->oprom_array); - - switch (cmd) { - case OPROMNEXT: node = __prom_getsibling(node); break; - case OPROMCHILD: node = __prom_getchild(node); break; - case OPROMSETCUR: break; - } - - data->current_node = node; - *((int *)opp->oprom_array) = node; - opp->oprom_size = sizeof(int); - - error = copyout(argp, opp, bufsize + sizeof(int)); + error = opromnext(argp, cmd, dp, opp, bufsize, data); break; case OPROMPCI2NODE: - error = -EINVAL; - - if (bufsize >= 2*sizeof(int)) { -#ifdef CONFIG_PCI - struct pci_dev *pdev; - struct pcidev_cookie *pcp; - pdev = pci_find_slot (((int *) opp->oprom_array)[0], - ((int *) opp->oprom_array)[1]); - - pcp = pdev->sysdata; - if (pcp != NULL && pcp->prom_node != -1 && pcp->prom_node) { - node = pcp->prom_node; - data->current_node = node; - *((int *)opp->oprom_array) = node; - opp->oprom_size = sizeof(int); - error = copyout(argp, opp, bufsize + sizeof(int)); - } -#endif - } + error = oprompci2node(argp, dp, opp, bufsize, data); break; case OPROMPATH2NODE: - node = prom_finddevice(opp->oprom_array); - data->current_node = node; - *((int *)opp->oprom_array) = node; - opp->oprom_size = sizeof(int); - - error = copyout(argp, opp, bufsize + sizeof(int)); + error = oprompath2node(argp, dp, opp, bufsize, data); break; case OPROMGETBOOTARGS: - buf = saved_command_line; - - len = strlen(buf); - - if (len > bufsize) { - error = -EINVAL; - break; - } - - strcpy(opp->oprom_array, buf); - opp->oprom_size = len; - - error = copyout(argp, opp, bufsize + sizeof(int)); + error = opromgetbootargs(argp, opp, bufsize); break; case OPROMU2P: @@ -297,25 +361,14 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, return error; } - -/* Return nonzero if a specific node is in the PROM device tree. */ -static int intree(int root, int node) +static struct device_node *get_node(phandle n, DATA *data) { - for (; root != 0; root = prom_getsibling(root)) - if (root == node || intree(prom_getchild(root),node)) - return 1; - return 0; -} + struct device_node *dp = of_find_node_by_phandle(n); -/* Return nonzero if a specific node is "valid". */ -static int goodnode(int n, DATA *data) -{ - if (n == data->lastnode || n == prom_root_node || n == options_node) - return 1; - if (n == 0 || n == -1 || !intree(prom_root_node,n)) - return 0; - data->lastnode = n; - return 1; + if (dp) + data->lastnode = dp; + + return dp; } /* Copy in a whole string from userspace into kernelspace. */ @@ -330,7 +383,7 @@ static int copyin_string(char __user *user, size_t len, char **ptr) if (!tmp) return -ENOMEM; - if(copy_from_user(tmp, user, len)) { + if (copy_from_user(tmp, user, len)) { kfree(tmp); return -EFAULT; } @@ -345,162 +398,187 @@ static int copyin_string(char __user *user, size_t len, char **ptr) /* * NetBSD /dev/openprom ioctl calls. */ -static int openprom_bsd_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) +static int opiocget(void __user *argp, DATA *data) { - DATA *data = (DATA *) file->private_data; - void __user *argp = (void __user *)arg; struct opiocdesc op; - int error, node, len; - char *str, *tmp; - char buffer[64]; - static int cnt; - - switch (cmd) { - case OPIOCGET: - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; - - if (!goodnode(op.op_nodeid,data)) - return -EINVAL; + struct device_node *dp; + char *str; + void *pval; + int err, len; - error = copyin_string(op.op_name, op.op_namelen, &str); - if (error) - return error; + if (copy_from_user(&op, argp, sizeof(op))) + return -EFAULT; - len = prom_getproplen(op.op_nodeid,str); + dp = get_node(op.op_nodeid, data); - if (len > op.op_buflen) { - kfree(str); - return -ENOMEM; - } + err = copyin_string(op.op_name, op.op_namelen, &str); + if (err) + return err; + pval = of_get_property(dp, str, &len); + err = 0; + if (!pval || len > op.op_buflen) { + err = -EINVAL; + } else { op.op_buflen = len; + if (copy_to_user(argp, &op, sizeof(op)) || + copy_to_user(op.op_buf, pval, len)) + err = -EFAULT; + } + kfree(str); - if (len <= 0) { - kfree(str); - /* Verified by the above copy_from_user */ - if (__copy_to_user(argp, &op, - sizeof(op))) - return -EFAULT; - return 0; - } + return err; +} - tmp = kmalloc(len + 1, GFP_KERNEL); - if (!tmp) { - kfree(str); - return -ENOMEM; - } +static int opiocnextprop(void __user *argp, DATA *data) +{ + struct opiocdesc op; + struct device_node *dp; + struct property *prop; + char *str; + int err, len; - cnt = prom_getproperty(op.op_nodeid, str, tmp, len); - if (cnt <= 0) { - error = -EINVAL; - } else { - tmp[len] = '\0'; + if (copy_from_user(&op, argp, sizeof(op))) + return -EFAULT; - if (__copy_to_user(argp, &op, sizeof(op)) != 0 || - copy_to_user(op.op_buf, tmp, len) != 0) - error = -EFAULT; - } + dp = get_node(op.op_nodeid, data); + if (!dp) + return -EINVAL; - kfree(tmp); - kfree(str); + err = copyin_string(op.op_name, op.op_namelen, &str); + if (err) + return err; - return error; + if (str[0] == '\0') { + prop = dp->properties; + } else { + prop = of_find_property(dp, str, NULL); + if (prop) + prop = prop->next; + } + kfree(str); - case OPIOCNEXTPROP: - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; + if (!prop) + len = 0; + else + len = prop->length; - if (!goodnode(op.op_nodeid,data)) - return -EINVAL; + if (len > op.op_buflen) + len = op.op_buflen; - error = copyin_string(op.op_name, op.op_namelen, &str); - if (error) - return error; + if (copy_to_user(argp, &op, sizeof(op))) + return -EFAULT; - tmp = prom_nextprop(op.op_nodeid,str,buffer); + if (len && + copy_to_user(op.op_buf, prop->value, len)) + return -EFAULT; - if (tmp) { - len = strlen(tmp); - if (len > op.op_buflen) - len = op.op_buflen; - else - op.op_buflen = len; - } else { - len = op.op_buflen = 0; - } + return 0; +} - if (!access_ok(VERIFY_WRITE, argp, sizeof(op))) { - kfree(str); - return -EFAULT; - } +static int opiocset(void __user *argp, DATA *data) +{ + struct opiocdesc op; + struct device_node *dp; + char *str, *tmp; + int err; - if (!access_ok(VERIFY_WRITE, op.op_buf, len)) { - kfree(str); - return -EFAULT; - } + if (copy_from_user(&op, argp, sizeof(op))) + return -EFAULT; + + dp = get_node(op.op_nodeid, data); + if (!dp) + return -EINVAL; - error = __copy_to_user(argp, &op, sizeof(op)); - if (!error) error = __copy_to_user(op.op_buf, tmp, len); + err = copyin_string(op.op_name, op.op_namelen, &str); + if (err) + return err; + err = copyin_string(op.op_buf, op.op_buflen, &tmp); + if (err) { kfree(str); + return err; + } - return error; + err = of_set_property(dp, str, tmp, op.op_buflen); - case OPIOCSET: - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; + kfree(str); + kfree(tmp); - if (!goodnode(op.op_nodeid,data)) - return -EINVAL; + return err; +} - error = copyin_string(op.op_name, op.op_namelen, &str); - if (error) - return error; +static int opiocgetnext(unsigned int cmd, void __user *argp) +{ + struct device_node *dp; + phandle nd; - error = copyin_string(op.op_buf, op.op_buflen, &tmp); - if (error) { - kfree(str); - return error; - } + BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); - len = prom_setprop(op.op_nodeid,str,tmp,op.op_buflen+1); + if (copy_from_user(&nd, argp, sizeof(phandle))) + return -EFAULT; - if (len != op.op_buflen) + if (nd == 0) { + if (cmd != OPIOCGETNEXT) return -EINVAL; + dp = of_find_node_by_path("/"); + } else { + dp = of_find_node_by_phandle(nd); + nd = 0; + if (dp) { + if (cmd == OPIOCGETNEXT) + dp = dp->sibling; + else + dp = dp->child; + } + } + if (dp) + nd = dp->node; + if (copy_to_user(argp, &nd, sizeof(phandle))) + return -EFAULT; - kfree(str); - kfree(tmp); + return 0; +} - return 0; +static int openprom_bsd_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + DATA *data = (DATA *) file->private_data; + void __user *argp = (void __user *)arg; + int err; - case OPIOCGETOPTNODE: - if (copy_to_user(argp, &options_node, sizeof(int))) - return -EFAULT; - return 0; + switch (cmd) { + case OPIOCGET: + err = opiocget(argp, data); + break; - case OPIOCGETNEXT: - case OPIOCGETCHILD: - if (copy_from_user(&node, argp, sizeof(int))) - return -EFAULT; + case OPIOCNEXTPROP: + err = opiocnextprop(argp, data); + break; - if (cmd == OPIOCGETNEXT) - node = __prom_getsibling(node); - else - node = __prom_getchild(node); + case OPIOCSET: + err = opiocset(argp, data); + break; + + case OPIOCGETOPTNODE: + BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); - if (__copy_to_user(argp, &node, sizeof(int))) + if (copy_to_user(argp, &options_node->node, sizeof(phandle))) return -EFAULT; return 0; + case OPIOCGETNEXT: + case OPIOCGETCHILD: + err = opiocgetnext(cmd, argp); + break; + default: - if (cnt++ < 10) - printk(KERN_INFO "openprom_bsd_ioctl: cmd 0x%X\n", cmd); return -EINVAL; - } + }; + + return err; } @@ -511,7 +589,6 @@ static int openprom_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { DATA *data = (DATA *) file->private_data; - static int cnt; switch (cmd) { case OPROMGETOPT: @@ -563,10 +640,8 @@ static int openprom_ioctl(struct inode * inode, struct file * file, return openprom_bsd_ioctl(inode,file,cmd,arg); default: - if (cnt++ < 10) - printk("openprom_ioctl: cmd 0x%X, arg 0x%lX\n", cmd, arg); return -EINVAL; - } + }; } static long openprom_compat_ioctl(struct file *file, unsigned int cmd, @@ -594,9 +669,7 @@ static long openprom_compat_ioctl(struct file *file, unsigned int cmd, case OPROMSETCUR: case OPROMPCI2NODE: case OPROMPATH2NODE: - lock_kernel(); rval = openprom_ioctl(file->f_dentry->d_inode, file, cmd, arg); - lock_kernel(); break; } @@ -607,13 +680,13 @@ static int openprom_open(struct inode * inode, struct file * file) { DATA *data; - data = (DATA *) kmalloc(sizeof(DATA), GFP_KERNEL); + data = kmalloc(sizeof(DATA), GFP_KERNEL); if (!data) return -ENOMEM; - data->current_node = prom_root_node; - data->lastnode = prom_root_node; - file->private_data = (void *)data; + data->current_node = of_find_node_by_path("/"); + data->lastnode = data->current_node; + file->private_data = (void *) data; return 0; } @@ -634,24 +707,30 @@ static struct file_operations openprom_fops = { }; static struct miscdevice openprom_dev = { - SUN_OPENPROM_MINOR, "openprom", &openprom_fops + .minor = SUN_OPENPROM_MINOR, + .name = "openprom", + .fops = &openprom_fops, }; static int __init openprom_init(void) { - int error; + struct device_node *dp; + int err; - error = misc_register(&openprom_dev); - if (error) { - printk(KERN_ERR "openprom: unable to get misc minor\n"); - return error; - } + err = misc_register(&openprom_dev); + if (err) + return err; - options_node = prom_getchild(prom_root_node); - options_node = prom_searchsiblings(options_node,"options"); + dp = of_find_node_by_path("/"); + dp = dp->child; + while (dp) { + if (!strcmp(dp->name, "options")) + break; + dp = dp->sibling; + } + options_node = dp; - if (options_node == 0 || options_node == -1) { - printk(KERN_ERR "openprom: unable to find options node\n"); + if (!options_node) { misc_deregister(&openprom_dev); return -EIO; } @@ -666,4 +745,3 @@ static void __exit openprom_cleanup(void) module_init(openprom_init); module_exit(openprom_cleanup); -MODULE_LICENSE("GPL"); diff --git a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c index d1babff6a53..2a9cc820442 100644 --- a/drivers/sbus/char/riowatchdog.c +++ b/drivers/sbus/char/riowatchdog.c @@ -211,7 +211,7 @@ static int __init riowd_bbc_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "bbc")) + if (!strcmp(edev->ofdev.node->name, "bbc")) goto found_bbc; } } @@ -238,7 +238,7 @@ static int __init riowd_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, RIOWD_NAME)) + if (!strcmp(edev->ofdev.node->name, RIOWD_NAME)) goto ebus_done; } } diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index e2d9a7c8542..575b1f7ed41 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -400,7 +400,7 @@ static int __init ts102_uctrl_init(void) } driver->regs->uctrl_intr = UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK; - printk("uctrl: 0x%x (irq %s)\n", driver->regs, __irq_itoa(driver->irq)); + printk("uctrl: 0x%x (irq %d)\n", driver->regs, driver->irq); uctrl_get_event_status(); uctrl_get_external_status(); return 0; diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h index 8045cd5e7cb..63941a259b9 100644 --- a/drivers/sbus/char/vfc.h +++ b/drivers/sbus/char/vfc.h @@ -1,8 +1,6 @@ #ifndef _LINUX_VFC_H_ #define _LINUX_VFC_H_ -#include <linux/devfs_fs_kernel.h> - /* * The control register for the vfc is at offset 0x4000 * The first field ram bank is located at offset 0x5000 diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index dfdd6be551f..55b2b31bd7a 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c @@ -164,10 +164,6 @@ int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance) return -EINVAL; if (init_vfc_hw(dev)) return -EIO; - - devfs_mk_cdev(MKDEV(VFC_MAJOR, instance), - S_IFCHR | S_IRUSR | S_IWUSR, - "vfc/%d", instance); return 0; } @@ -623,7 +619,7 @@ static int vfc_mmap(struct file *file, struct vm_area_struct *vma) map_size = sizeof(struct vfc_regs); vma->vm_flags |= - (VM_SHM | VM_LOCKED | VM_IO | VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE); + (VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE); map_offset = (unsigned int) (long)dev->phys_regs; ret = io_remap_pfn_range(vma, vma->vm_start, MK_IOSPACE_PFN(dev->which_io, @@ -677,7 +673,6 @@ static int vfc_probe(void) kfree(vfc_dev_lst); return -EIO; } - devfs_mk_dir("vfc"); instance = 0; for_all_sbusdev(sdev, sbus) { if (strcmp(sdev->prom_name, "vfc") == 0) { @@ -717,7 +712,6 @@ static void deinit_vfc_device(struct vfc_dev *dev) { if(dev == NULL) return; - devfs_remove("vfc/%d", dev->instance); sbus_iounmap(dev->regs, sizeof(struct vfc_regs)); kfree(dev); } @@ -731,7 +725,6 @@ void cleanup_module(void) for (devp = vfc_dev_lst; *devp; devp++) deinit_vfc_device(*devp); - devfs_remove("vfc"); kfree(vfc_dev_lst); return; } |