// SPDX-License-Identifier: GPL-2.0-or-later /* * Linux/SPARC PROM Configuration Driver * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * * This character device driver allows user programs to access the * PROM device tree. It is compatible with the SunOS /dev/openprom * driver and the NetBSD /dev/openprom driver. The SunOS eeprom * utility works without any modifications. * * The driver uses a minor number under the misc device major. The * file read/write mode determines the type of access to the PROM. * Interrupts are disabled whenever the driver calls into the PROM for * sanity's sake.
*/
MODULE_AUTHOR("Thomas K. Dyas and Eddie C. Dost ");
MODULE_DESCRIPTION("OPENPROM Configuration Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
MODULE_ALIAS_MISCDEV(SUN_OPENPROM_MINOR);
/* Private data kept by the driver for each descriptor. */ typedefstruct openprom_private_data
{ 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 DEFINE_MUTEX(openprom_mutex); staticstruct device_node *options_node;
/* * Copy an openpromio structure into kernel space from user space. * This routine does error checking to make sure that all memory * accesses are within bounds. A pointer to the allocated openpromio * structure will be placed in "*opp_p". Return value is the length * of the user supplied buffer.
*/ staticint copyin(struct openpromio __user *info, struct openpromio **opp_p)
{ unsignedint bufsize;
if (!info || !opp_p) return -EFAULT;
if (get_user(bufsize, &info->oprom_size)) return -EFAULT;
if (bufsize == 0) return -EINVAL;
/* If the bufsize is too large, just limit it. * Fix from Jason Rappleye.
*/ if (bufsize > OPROMMAXPARAM)
bufsize = OPROMMAXPARAM;
n = bufsize = 0; while ((n < 2) && (bufsize < OPROMMAXPARAM)) { if (get_user(c, &info->oprom_array[bufsize])) {
kfree(*opp_p); return -EFAULT;
} if (c == '\0')
n++;
(*opp_p)->oprom_array[bufsize++] = c;
} if (!n) {
kfree(*opp_p); return -EINVAL;
} return bufsize;
}
/* * Copy an openpromio structure in kernel space back to user space.
*/ staticint copyout(void __user *info, struct openpromio *opp, int len)
{ if (copy_to_user(info, opp, len)) return -EFAULT; return 0;
}
staticint opromgetprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize)
{ constvoid *pval; int len;
if (!dp ||
!(pval = of_get_property(dp, op->oprom_array, &len)) ||
len <= 0 || len > bufsize) return copyout(argp, op, sizeof(int));
/* * Handoff control to the correct ioctl handler.
*/ staticlong openprom_ioctl(struct file * file, unsignedint cmd, unsignedlong arg)
{
DATA *data = file->private_data;
switch (cmd) { case OPROMGETOPT: case OPROMNXTOPT: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; return openprom_sunos_ioctl(file, cmd, arg,
options_node);
case OPROMSETOPT: case OPROMSETOPT2: if ((file->f_mode & FMODE_WRITE) == 0) return -EPERM; return openprom_sunos_ioctl(file, cmd, arg,
options_node);
case OPROMNEXT: case OPROMCHILD: case OPROMGETPROP: case OPROMNXTPROP: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; return openprom_sunos_ioctl(file, cmd, arg,
data->current_node);
case OPROMU2P: case OPROMGETCONS: case OPROMGETFBNAME: case OPROMGETBOOTARGS: case OPROMSETCUR: case OPROMPCI2NODE: case OPROMPATH2NODE: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; return openprom_sunos_ioctl(file, cmd, arg, NULL);
case OPIOCGET: case OPIOCNEXTPROP: case OPIOCGETOPTNODE: case OPIOCGETNEXT: case OPIOCGETCHILD: if ((file->f_mode & FMODE_READ) == 0) return -EBADF; return openprom_bsd_ioctl(file,cmd,arg);
case OPIOCSET: if ((file->f_mode & FMODE_WRITE) == 0) return -EBADF; return openprom_bsd_ioctl(file,cmd,arg);
/* * SunOS/Solaris only, the NetBSD one's have embedded pointers in * the arg which we'd need to clean up...
*/ switch (cmd) { case OPROMGETOPT: case OPROMSETOPT: case OPROMNXTOPT: case OPROMSETOPT2: case OPROMNEXT: case OPROMCHILD: case OPROMGETPROP: case OPROMNXTPROP: case OPROMU2P: case OPROMGETCONS: case OPROMGETFBNAME: case OPROMGETBOOTARGS: case OPROMSETCUR: case OPROMPCI2NODE: case OPROMPATH2NODE:
rval = openprom_ioctl(file, cmd, arg); break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.