- Move OFW_NAME_MAX, used as a limit for OFW property names and device
identifiers, to openfirmio.h as OFIOCMAXNAME, so programs can use it for buffer sizes etc. Note: Although this is only a rough upper limit to make the code more robust and to prevent the allocation of ridiculous amounts of memory, the current limit of one page (8191 + '\0' in openfirm_getstr()) still appears a bit high. The maximum length of OFW property names is 31. I didn't find a maximum length for the device identifiers in the OFW documentation but it certainly is much smaller than 8191, too. - Enable the OFIOCSET ioctl, i.e. move it out from under #if 0. - Don't use openfirm_getstr() for the property value in OFIOCSET, there are also properties whose values aren't strings and it makes sense to use a different maximum length for property values than OFW_NAME_MAX/ OFIOCMAXNAME. The maximum accepted property value is defined in openfirmio.h as OFIOCMAXVALUE (currently the maximum size of the value of the nvramrc property). - Make OFIOCSET not return EINVAL when OF_setprop() returns a different length for the written value than it was told to write, this is normal for the text string values of the properties in the OFW /options node. Instead, only return EINVAL if OF_setprop() returned -1 (value could not be written or property could not be created). Add a comment about the specialty of the OFW /options node. - Make OFIOCSET return the length of the written value returned by OF_setprop(), just like OF_getprop() does. Quite useful, at least for debugging. Reviewed by: tmm
This commit is contained in:
parent
7f21753e25
commit
073e8552f8
@ -74,9 +74,6 @@ static phandle_t lastnode; /* speed hack */
|
||||
static int openfirm_checkid(phandle_t, phandle_t);
|
||||
static int openfirm_getstr(int, const char *, char **);
|
||||
|
||||
/* Maximum accepted name length. */
|
||||
#define OFW_NAME_MAX 8191
|
||||
|
||||
/*
|
||||
* Verify target ID is valid (exists in the OPENPROM tree), as
|
||||
* listed from node ID sid forward.
|
||||
@ -99,7 +96,7 @@ openfirm_getstr(int len, const char *user, char **cpp)
|
||||
char *cp;
|
||||
|
||||
/* Reject obvious bogus requests */
|
||||
if ((u_int)len > OFW_NAME_MAX)
|
||||
if ((u_int)len > OFIOCMAXNAME)
|
||||
return (ENAMETOOLONG);
|
||||
|
||||
*cpp = cp = malloc(len + 1, M_TEMP, M_WAITOK);
|
||||
@ -129,9 +126,7 @@ openfirm_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags,
|
||||
*(phandle_t *) data = OF_finddevice("/options");
|
||||
return (0);
|
||||
case OFIOCGET:
|
||||
#if 0
|
||||
case OFIOCSET:
|
||||
#endif
|
||||
case OFIOCNEXTPROP:
|
||||
case OFIOCFINDDEVICE:
|
||||
case OFIOCGETPROPLEN:
|
||||
@ -186,23 +181,36 @@ openfirm_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags,
|
||||
error = copyout(value, of->of_buf, len);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case OFIOCSET:
|
||||
/*
|
||||
* Note: Text string values for at least the /options node
|
||||
* have to be null-terminated and the length paramter must
|
||||
* include this terminating null. However, like OF_getprop(),
|
||||
* OF_setprop() will return the the actual length of the text
|
||||
* string, i.e. omitting the terminating null.
|
||||
*/
|
||||
if ((flags & FWRITE) == 0)
|
||||
return (EBADF);
|
||||
if (node == 0)
|
||||
return (EINVAL);
|
||||
if ((u_int)of->of_buflen > OFIOCMAXVALUE)
|
||||
return (ENAMETOOLONG);
|
||||
error = openfirm_getstr(of->of_namelen, of->of_name, &name);
|
||||
if (error)
|
||||
break;
|
||||
error = openfirm_getstr(of->of_buflen, of->of_buf, &value);
|
||||
value = malloc(of->of_buflen, M_TEMP, M_WAITOK);
|
||||
if (value == NULL) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
error = copyin(of->of_buf, value, of->of_buflen);
|
||||
if (error)
|
||||
break;
|
||||
len = OF_setprop(node, name, value, of->of_buflen);
|
||||
if (len != of->of_buflen)
|
||||
if (len < 0)
|
||||
error = EINVAL;
|
||||
of->of_buflen = len;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case OFIOCNEXTPROP:
|
||||
if (node == 0 || of->of_buflen < 0)
|
||||
|
@ -54,10 +54,8 @@ struct ofiocdesc {
|
||||
|
||||
/* Get openprom field. */
|
||||
#define OFIOCGET _IOWR(OFIOC_BASE, 1, struct ofiocdesc)
|
||||
#if 0
|
||||
/* Set openprom field. */
|
||||
#define OFIOCSET _IOW(OFIOC_BASE, 2, struct ofiocdesc)
|
||||
#endif
|
||||
#define OFIOCSET _IOWR(OFIOC_BASE, 2, struct ofiocdesc)
|
||||
/* Get next property. */
|
||||
#define OFIOCNEXTPROP _IOWR(OFIOC_BASE, 3, struct ofiocdesc)
|
||||
/* Get options node. */
|
||||
@ -71,4 +69,9 @@ struct ofiocdesc {
|
||||
/* Retrieve the size of a property. */
|
||||
#define OFIOCGETPROPLEN _IOWR(OFIOC_BASE, 8, struct ofiocdesc)
|
||||
|
||||
/* Maximum accepted name length. */
|
||||
#define OFIOCMAXNAME 8191
|
||||
/* Maximum accepted value length (maximum of nvramrc property). */
|
||||
#define OFIOCMAXVALUE 8192
|
||||
|
||||
#endif /* _DEV_OFW_OPENFIRMIO_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user