|
Lines 68-85
Link Here
|
| 68 |
size_t count, loff_t *ppos) |
68 |
size_t count, loff_t *ppos) |
| 69 |
{ |
69 |
{ |
| 70 |
struct inode *inode = file->f_dentry->d_inode; |
70 |
struct inode *inode = file->f_dentry->d_inode; |
|
|
71 |
loff_t pos = *ppos; |
| 71 |
char buffer[10]; |
72 |
char buffer[10]; |
| 72 |
|
73 |
|
|
|
74 |
/* FIXME: add proper seek locking */ |
| 75 |
if (pos != (unsigned int)pos || pos >= 9) |
| 76 |
return -0; |
| 77 |
|
| 73 |
if (count < 0 || !inode->u.generic_ip) |
78 |
if (count < 0 || !inode->u.generic_ip) |
| 74 |
return -EINVAL; |
79 |
return -EINVAL; |
| 75 |
sprintf (buffer, "%8.8x\n", (u32)(long)(inode->u.generic_ip)); |
80 |
sprintf (buffer, "%8.8x\n", (u32)(long)(inode->u.generic_ip)); |
| 76 |
if (file->f_pos >= 9) |
81 |
if (count > 9 - pos) |
| 77 |
return 0; |
82 |
count = 9 - pos; |
| 78 |
if (count > 9 - file->f_pos) |
83 |
if (copy_to_user(buf, buffer + pos, count)) |
| 79 |
count = 9 - file->f_pos; |
|
|
| 80 |
if (copy_to_user(buf, buffer + file->f_pos, count)) |
| 81 |
return -EFAULT; |
84 |
return -EFAULT; |
| 82 |
file->f_pos += count; |
85 |
*ppos = pos + count; |
| 83 |
return count; |
86 |
return count; |
| 84 |
} |
87 |
} |
| 85 |
|
88 |
|
|
Lines 93-100
Link Here
|
| 93 |
u32 *q; |
96 |
u32 *q; |
| 94 |
openprom_property *op; |
97 |
openprom_property *op; |
| 95 |
char buffer[64]; |
98 |
char buffer[64]; |
|
|
99 |
loff_t pos = *ppos; |
| 96 |
|
100 |
|
| 97 |
if (filp->f_pos >= 0xffffff || count >= 0xffffff) |
101 |
/* FIXME: add proper seek locking */ |
|
|
102 |
|
| 103 |
if (pos < 0 || pos >= 0xffffff || count >= 0xffffff) |
| 98 |
return -EINVAL; |
104 |
return -EINVAL; |
| 99 |
if (!filp->private_data) { |
105 |
if (!filp->private_data) { |
| 100 |
node = nodes[(u16)((long)inode->u.generic_ip)].node; |
106 |
node = nodes[(u16)((long)inode->u.generic_ip)].node; |
|
Lines 180-186
Link Here
|
| 180 |
} else { |
186 |
} else { |
| 181 |
i = (op->len << 1) + 1; |
187 |
i = (op->len << 1) + 1; |
| 182 |
} |
188 |
} |
| 183 |
k = filp->f_pos; |
189 |
k = pos; |
| 184 |
if (k >= i) return 0; |
190 |
if (k >= i) return 0; |
| 185 |
if (count > i - k) count = i - k; |
191 |
if (count > i - k) count = i - k; |
| 186 |
if (op->flag & OPP_STRING) { |
192 |
if (op->flag & OPP_STRING) { |
|
Lines 197-203
Link Here
|
| 197 |
j = count; |
203 |
j = count; |
| 198 |
|
204 |
|
| 199 |
if (j >= 0) { |
205 |
if (j >= 0) { |
| 200 |
if (copy_to_user(buf + k - filp->f_pos, |
206 |
if (copy_to_user(buf + k - pos, |
| 201 |
op->value + k - 1, j)) |
207 |
op->value + k - 1, j)) |
| 202 |
return -EFAULT; |
208 |
return -EFAULT; |
| 203 |
count -= j; |
209 |
count -= j; |
|
Lines 205-215
Link Here
|
| 205 |
} |
211 |
} |
| 206 |
|
212 |
|
| 207 |
if (count) { |
213 |
if (count) { |
| 208 |
if (put_user('\'', &buf [k++ - filp->f_pos])) |
214 |
if (put_user('\'', &buf [k++ - pos])) |
| 209 |
return -EFAULT; |
215 |
return -EFAULT; |
| 210 |
} |
216 |
} |
| 211 |
if (count > 1) { |
217 |
if (count > 1) { |
| 212 |
if (put_user('\n', &buf [k++ - filp->f_pos])) |
218 |
if (put_user('\n', &buf [k++ - pos])) |
| 213 |
return -EFAULT; |
219 |
return -EFAULT; |
| 214 |
} |
220 |
} |
| 215 |
} else if (op->flag & OPP_STRINGLIST) { |
221 |
} else if (op->flag & OPP_STRINGLIST) { |
|
Lines 287-293
Link Here
|
| 287 |
if ((k < i - 1) && (k & 1)) { |
293 |
if ((k < i - 1) && (k & 1)) { |
| 288 |
sprintf (buffer, "%02x", |
294 |
sprintf (buffer, "%02x", |
| 289 |
(unsigned char) *(op->value + (k >> 1)) & 0xff); |
295 |
(unsigned char) *(op->value + (k >> 1)) & 0xff); |
| 290 |
if (put_user(buffer[1], &buf[k++ - filp->f_pos])) |
296 |
if (put_user(buffer[1], &buf[k++ - pos])) |
| 291 |
return -EFAULT; |
297 |
return -EFAULT; |
| 292 |
count--; |
298 |
count--; |
| 293 |
} |
299 |
} |
|
Lines 295-301
Link Here
|
| 295 |
for (; (count > 1) && (k < i - 1); k += 2) { |
301 |
for (; (count > 1) && (k < i - 1); k += 2) { |
| 296 |
sprintf (buffer, "%02x", |
302 |
sprintf (buffer, "%02x", |
| 297 |
(unsigned char) *(op->value + (k >> 1)) & 0xff); |
303 |
(unsigned char) *(op->value + (k >> 1)) & 0xff); |
| 298 |
if (copy_to_user(buf + k - filp->f_pos, buffer, 2)) |
304 |
if (copy_to_user(buf + k - pos, buffer, 2)) |
| 299 |
return -EFAULT; |
305 |
return -EFAULT; |
| 300 |
count -= 2; |
306 |
count -= 2; |
| 301 |
} |
307 |
} |
|
Lines 303-340
Link Here
|
| 303 |
if (count && (k < i - 1)) { |
309 |
if (count && (k < i - 1)) { |
| 304 |
sprintf (buffer, "%02x", |
310 |
sprintf (buffer, "%02x", |
| 305 |
(unsigned char) *(op->value + (k >> 1)) & 0xff); |
311 |
(unsigned char) *(op->value + (k >> 1)) & 0xff); |
| 306 |
if (put_user(buffer[0], &buf[k++ - filp->f_pos])) |
312 |
if (put_user(buffer[0], &buf[k++ - pos])) |
| 307 |
return -EFAULT; |
313 |
return -EFAULT; |
| 308 |
count--; |
314 |
count--; |
| 309 |
} |
315 |
} |
| 310 |
|
316 |
|
| 311 |
if (count) { |
317 |
if (count) { |
| 312 |
if (put_user('\n', &buf [k++ - filp->f_pos])) |
318 |
if (put_user('\n', &buf [k++ - pos])) |
| 313 |
return -EFAULT; |
319 |
return -EFAULT; |
| 314 |
} |
320 |
} |
| 315 |
} |
321 |
} |
| 316 |
count = k - filp->f_pos; |
322 |
count = k - pos; |
| 317 |
filp->f_pos = k; |
323 |
*ppos = k; |
| 318 |
return count; |
324 |
return count; |
| 319 |
} |
325 |
} |
| 320 |
|
326 |
|
| 321 |
static ssize_t property_write(struct file *filp, const char *buf, |
327 |
static ssize_t property_write(struct file *filp, const char *buf, |
| 322 |
size_t count, loff_t *ppos) |
328 |
size_t count, loff_t *ppos) |
| 323 |
{ |
329 |
{ |
|
|
330 |
loff_t pos = *ppos; |
| 324 |
int i, j, k; |
331 |
int i, j, k; |
| 325 |
char *p; |
332 |
char *p; |
| 326 |
u32 *q; |
333 |
u32 *q; |
| 327 |
void *b; |
334 |
void *b; |
| 328 |
openprom_property *op; |
335 |
openprom_property *op; |
| 329 |
|
336 |
|
| 330 |
if (filp->f_pos >= 0xffffff || count >= 0xffffff) |
337 |
/* FIXME: add proper seek locking */ |
|
|
338 |
|
| 339 |
if (pos < 0 || pos >= 0xffffff || count >= 0xffffff) |
| 331 |
return -EINVAL; |
340 |
return -EINVAL; |
| 332 |
if (!filp->private_data) { |
341 |
if (!filp->private_data) { |
| 333 |
i = property_read (filp, NULL, 0, 0); |
342 |
i = property_read (filp, NULL, 0, 0); |
| 334 |
if (i) |
343 |
if (i) |
| 335 |
return i; |
344 |
return i; |
| 336 |
} |
345 |
} |
| 337 |
k = filp->f_pos; |
346 |
k = pos; |
| 338 |
op = (openprom_property *)filp->private_data; |
347 |
op = (openprom_property *)filp->private_data; |
| 339 |
if (!(op->flag & OPP_STRING)) { |
348 |
if (!(op->flag & OPP_STRING)) { |
| 340 |
u32 *first, *last; |
349 |
u32 *first, *last; |
|
Lines 462-468
Link Here
|
| 462 |
op->len = i; |
471 |
op->len = i; |
| 463 |
} else |
472 |
} else |
| 464 |
op->len = i; |
473 |
op->len = i; |
| 465 |
filp->f_pos += count; |
474 |
pos += count; |
| 466 |
} |
475 |
} |
| 467 |
write_try_string: |
476 |
write_try_string: |
| 468 |
if (!(op->flag & OPP_BINARY)) { |
477 |
if (!(op->flag & OPP_BINARY)) { |
|
Lines 480-486
Link Here
|
| 480 |
op->flag |= OPP_QUOTED; |
489 |
op->flag |= OPP_QUOTED; |
| 481 |
buf++; |
490 |
buf++; |
| 482 |
count--; |
491 |
count--; |
| 483 |
filp->f_pos++; |
492 |
pos++; |
|
|
493 |
*ppos = pos; |
| 484 |
if (!count) { |
494 |
if (!count) { |
| 485 |
op->flag |= OPP_STRING; |
495 |
op->flag |= OPP_STRING; |
| 486 |
return 1; |
496 |
return 1; |
|
Lines 489-497
Link Here
|
| 489 |
op->flag |= OPP_NOTQUOTED; |
499 |
op->flag |= OPP_NOTQUOTED; |
| 490 |
} |
500 |
} |
| 491 |
op->flag |= OPP_STRING; |
501 |
op->flag |= OPP_STRING; |
| 492 |
if (op->alloclen <= count + filp->f_pos) { |
502 |
if (op->alloclen <= count + pos) { |
| 493 |
b = kmalloc (sizeof (openprom_property) |
503 |
b = kmalloc (sizeof (openprom_property) |
| 494 |
+ 2 * (count + filp->f_pos), GFP_KERNEL); |
504 |
+ 2 * (count + pos), GFP_KERNEL); |
| 495 |
if (!b) |
505 |
if (!b) |
| 496 |
return -ENOMEM; |
506 |
return -ENOMEM; |
| 497 |
memcpy (b, filp->private_data, |
507 |
memcpy (b, filp->private_data, |
|
Lines 499-512
Link Here
|
| 499 |
+ strlen (op->name) + op->alloclen); |
509 |
+ strlen (op->name) + op->alloclen); |
| 500 |
memset (((char *)b) + sizeof (openprom_property) |
510 |
memset (((char *)b) + sizeof (openprom_property) |
| 501 |
+ strlen (op->name) + op->alloclen, |
511 |
+ strlen (op->name) + op->alloclen, |
| 502 |
0, 2*(count - filp->f_pos) - op->alloclen); |
512 |
0, 2*(count - pos) - op->alloclen); |
| 503 |
op = (openprom_property *)b; |
513 |
op = (openprom_property *)b; |
| 504 |
op->alloclen = 2*(count + filp->f_pos); |
514 |
op->alloclen = 2*(count + pos); |
| 505 |
b = filp->private_data; |
515 |
b = filp->private_data; |
| 506 |
filp->private_data = (void *)op; |
516 |
filp->private_data = (void *)op; |
| 507 |
kfree (b); |
517 |
kfree (b); |
| 508 |
} |
518 |
} |
| 509 |
p = op->value + filp->f_pos - ((op->flag & OPP_QUOTED) ? 1 : 0); |
519 |
p = op->value + pos - ((op->flag & OPP_QUOTED) ? 1 : 0); |
| 510 |
if (copy_from_user(p, buf, count)) |
520 |
if (copy_from_user(p, buf, count)) |
| 511 |
return -EFAULT; |
521 |
return -EFAULT; |
| 512 |
op->flag |= OPP_DIRTY; |
522 |
op->flag |= OPP_DIRTY; |
|
Lines 517-533
Link Here
|
| 517 |
} |
527 |
} |
| 518 |
if (i < count) { |
528 |
if (i < count) { |
| 519 |
op->len = p - op->value; |
529 |
op->len = p - op->value; |
| 520 |
filp->f_pos += i + 1; |
530 |
pos += i + 1; |
|
|
531 |
*ppos = pos; |
| 521 |
if ((p > op->value) && (op->flag & OPP_QUOTED) |
532 |
if ((p > op->value) && (op->flag & OPP_QUOTED) |
| 522 |
&& (*(p - 1) == '\'')) |
533 |
&& (*(p - 1) == '\'')) |
| 523 |
op->len--; |
534 |
op->len--; |
| 524 |
} else { |
535 |
} else { |
| 525 |
if (p - op->value > op->len) |
536 |
if (p - op->value > op->len) |
| 526 |
op->len = p - op->value; |
537 |
op->len = p - op->value; |
| 527 |
filp->f_pos += count; |
538 |
pos += count; |
|
|
539 |
*ppos = pos; |
| 528 |
} |
540 |
} |
| 529 |
} |
541 |
} |
| 530 |
return filp->f_pos - k; |
542 |
return pos - k; |
| 531 |
} |
543 |
} |
| 532 |
|
544 |
|
| 533 |
int property_release (struct inode *inode, struct file *filp) |
545 |
int property_release (struct inode *inode, struct file *filp) |