static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len) { static struct property *tmp = NULL; struct property *p; const char *name; if (tmp) { p = tmp; memset(p, 0, sizeof(*p) + 32); tmp = NULL; } else { p = prom_early_alloc(sizeof(struct property) + 32); p->unique_id = prom_unique_id++; } p->name = (char *) (p + 1); if (special_name) { strcpy(p->name, special_name); p->length = special_len; p->value = prom_early_alloc(special_len); memcpy(p->value, special_val, special_len); } else { if (prev == NULL) { name = prom_firstprop(node, p->name); } else { name = prom_nextprop(node, prev, p->name); } if (!name || strlen(name) == 0) { tmp = p; return NULL; } #ifdef CONFIG_SPARC32 strcpy(p->name, name); #endif p->length = prom_getproplen(node, p->name); if (p->length <= 0) { p->length = 0; } else { int len; p->value = prom_early_alloc(p->length + 1); len = prom_getproperty(node, p->name, p->value, p->length); if (len <= 0) p->length = 0; ((unsigned char *)p->value)[p->length] = '\0'; } } return p; }
static ssize_t property_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { struct inode *inode = filp->f_dentry->d_inode; int i, j, k; u32 node; char *p, *s; u32 *q; openprom_property *op; char buffer[64]; if (filp->f_pos >= 0xffffff || count >= 0xffffff) return -EINVAL; if (!filp->private_data) { node = nodes[(u16)((long)inode->u.generic_ip)].node; i = ((u32)(long)inode->u.generic_ip) >> 16; if ((u16)((long)inode->u.generic_ip) == aliases) { if (i >= aliases_nodes) p = NULL; else p = alias_names [i]; } else for (p = prom_firstprop (node, buffer); i && p && *p; p = prom_nextprop (node, p, buffer), i--) /* nothing */ ; if (!p || !*p) return -EIO; i = prom_getproplen (node, p); if (i < 0) { if ((u16)((long)inode->u.generic_ip) == aliases) i = 0; else return -EIO; } k = i; if (i < 64) i = 64; filp->private_data = kmalloc (sizeof (openprom_property) + (j = strlen (p)) + 2 * i, GFP_KERNEL); if (!filp->private_data) return -ENOMEM; op = (openprom_property *)filp->private_data; op->flag = 0; op->alloclen = 2 * i; strcpy (op->name, p); op->value = (char *)(((unsigned long)(op->name + j + 4)) & ~3); op->len = k; if (k && prom_getproperty (node, p, op->value, i) < 0) return -EIO; op->value [k] = 0; if (k) { for (s = NULL, p = op->value; p < op->value + k; p++) { if ((*p >= ' ' && *p <= '~') || *p == '\n') { op->flag |= OPP_STRING; s = p; continue; } if (p > op->value && !*p && s == p - 1) { if (p < op->value + k - 1) op->flag |= OPP_STRINGLIST; else op->flag |= OPP_ASCIIZ; continue; } if (k == 1 && !*p) { op->flag |= (OPP_STRING|OPP_ASCIIZ); break; } op->flag &= ~(OPP_STRING|OPP_STRINGLIST); if (k & 3) op->flag |= OPP_HEXSTRING; else op->flag |= OPP_BINARY; break; } if (op->flag & OPP_STRINGLIST) op->flag &= ~(OPP_STRING); if (op->flag & OPP_ASCIIZ) op->len--; } } else