|
Lines 69-85
Link Here
|
| 69 |
size_t count, loff_t *ppos) |
69 |
size_t count, loff_t *ppos) |
| 70 |
{ |
70 |
{ |
| 71 |
struct inode *inode = file->f_dentry->d_inode; |
71 |
struct inode *inode = file->f_dentry->d_inode; |
|
|
72 |
loff_t pos = *ppos; |
| 72 |
char buffer[10]; |
73 |
char buffer[10]; |
| 73 |
|
74 |
|
| 74 |
if (count < 0 || !inode->u.generic_ip) |
75 |
if (count < 0 || !inode->u.generic_ip) |
| 75 |
return -EINVAL; |
76 |
return -EINVAL; |
| 76 |
sprintf (buffer, "%8.8x\n", (u32)(long)(inode->u.generic_ip)); |
77 |
sprintf (buffer, "%8.8x\n", (u32)(long)(inode->u.generic_ip)); |
| 77 |
if (file->f_pos >= 9) |
78 |
if (pos != (unsigned)pos || pos >= 9) |
| 78 |
return 0; |
79 |
return 0; |
| 79 |
if (count > 9 - file->f_pos) |
80 |
if (count > 9 - pos) |
| 80 |
count = 9 - file->f_pos; |
81 |
count = 9 - pos; |
| 81 |
copy_to_user(buf, buffer + file->f_pos, count); |
82 |
copy_to_user(buf, buffer + pos, count); |
| 82 |
file->f_pos += count; |
83 |
*ppos = pos + count; |
| 83 |
return count; |
84 |
return count; |
| 84 |
} |
85 |
} |
| 85 |
|
86 |
|
|
Lines 87-92
Link Here
|
| 87 |
size_t count, loff_t *ppos) |
88 |
size_t count, loff_t *ppos) |
| 88 |
{ |
89 |
{ |
| 89 |
struct inode *inode = filp->f_dentry->d_inode; |
90 |
struct inode *inode = filp->f_dentry->d_inode; |
|
|
91 |
loff_t pos = *ppos; |
| 90 |
int i, j, k; |
92 |
int i, j, k; |
| 91 |
u32 node; |
93 |
u32 node; |
| 92 |
char *p, *s; |
94 |
char *p, *s; |
|
Lines 94-100
Link Here
|
| 94 |
openprom_property *op; |
96 |
openprom_property *op; |
| 95 |
char buffer[64]; |
97 |
char buffer[64]; |
| 96 |
|
98 |
|
| 97 |
if (filp->f_pos >= 0xffffff) |
99 |
if (pos < 0 || pos >= 0xffffff) |
| 98 |
return -EINVAL; |
100 |
return -EINVAL; |
| 99 |
if (!filp->private_data) { |
101 |
if (!filp->private_data) { |
| 100 |
node = nodes[(u16)((long)inode->u.generic_ip)].node; |
102 |
node = nodes[(u16)((long)inode->u.generic_ip)].node; |
|
Lines 180-186
Link Here
|
| 180 |
} else { |
182 |
} else { |
| 181 |
i = (op->len << 1) + 1; |
183 |
i = (op->len << 1) + 1; |
| 182 |
} |
184 |
} |
| 183 |
k = filp->f_pos; |
185 |
k = pos; |
| 184 |
if (k >= i) return 0; |
186 |
if (k >= i) return 0; |
| 185 |
if (count > i - k) count = i - k; |
187 |
if (count > i - k) count = i - k; |
| 186 |
if (op->flag & OPP_STRING) { |
188 |
if (op->flag & OPP_STRING) { |
|
Lines 196-211
Link Here
|
| 196 |
j = count; |
198 |
j = count; |
| 197 |
|
199 |
|
| 198 |
if (j >= 0) { |
200 |
if (j >= 0) { |
| 199 |
copy_to_user(buf + k - filp->f_pos, |
201 |
copy_to_user(buf + k - pos, |
| 200 |
op->value + k - 1, j); |
202 |
op->value + k - 1, j); |
| 201 |
count -= j; |
203 |
count -= j; |
| 202 |
k += j; |
204 |
k += j; |
| 203 |
} |
205 |
} |
| 204 |
|
206 |
|
| 205 |
if (count) |
207 |
if (count) |
| 206 |
__put_user('\'', &buf [k++ - filp->f_pos]); |
208 |
__put_user('\'', &buf [k++ - pos]); |
| 207 |
if (count > 1) |
209 |
if (count > 1) |
| 208 |
__put_user('\n', &buf [k++ - filp->f_pos]); |
210 |
__put_user('\n', &buf [k++ - pos]); |
| 209 |
|
211 |
|
| 210 |
} else if (op->flag & OPP_STRINGLIST) { |
212 |
} else if (op->flag & OPP_STRINGLIST) { |
| 211 |
char *tmp; |
213 |
char *tmp; |
|
Lines 273-319
Link Here
|
| 273 |
|
275 |
|
| 274 |
if ((k < i - 1) && (k & 1)) { |
276 |
if ((k < i - 1) && (k & 1)) { |
| 275 |
sprintf (buffer, "%02x", *(op->value + (k >> 1))); |
277 |
sprintf (buffer, "%02x", *(op->value + (k >> 1))); |
| 276 |
__put_user(buffer[1], &buf[k++ - filp->f_pos]); |
278 |
__put_user(buffer[1], &buf[k++ - pos]); |
| 277 |
count--; |
279 |
count--; |
| 278 |
} |
280 |
} |
| 279 |
|
281 |
|
| 280 |
for (; (count > 1) && (k < i - 1); k += 2) { |
282 |
for (; (count > 1) && (k < i - 1); k += 2) { |
| 281 |
sprintf (buffer, "%02x", *(op->value + (k >> 1))); |
283 |
sprintf (buffer, "%02x", *(op->value + (k >> 1))); |
| 282 |
copy_to_user (buf + k - filp->f_pos, buffer, 2); |
284 |
copy_to_user (buf + k - pos, buffer, 2); |
| 283 |
count -= 2; |
285 |
count -= 2; |
| 284 |
} |
286 |
} |
| 285 |
|
287 |
|
| 286 |
if (count && (k < i - 1)) { |
288 |
if (count && (k < i - 1)) { |
| 287 |
sprintf (buffer, "%02x", *(op->value + (k >> 1))); |
289 |
sprintf (buffer, "%02x", *(op->value + (k >> 1))); |
| 288 |
__put_user(buffer[0], &buf[k++ - filp->f_pos]); |
290 |
__put_user(buffer[0], &buf[k++ - pos]); |
| 289 |
count--; |
291 |
count--; |
| 290 |
} |
292 |
} |
| 291 |
|
293 |
|
| 292 |
if (count) |
294 |
if (count) |
| 293 |
__put_user('\n', &buf [k++ - filp->f_pos]); |
295 |
__put_user('\n', &buf [k++ - pos]); |
| 294 |
} |
296 |
} |
| 295 |
count = k - filp->f_pos; |
297 |
count = k - pos; |
| 296 |
filp->f_pos = k; |
298 |
*ppos = k; |
| 297 |
return count; |
299 |
return count; |
| 298 |
} |
300 |
} |
| 299 |
|
301 |
|
| 300 |
static ssize_t property_write(struct file *filp, const char *buf, |
302 |
static ssize_t property_write(struct file *filp, const char *buf, |
| 301 |
size_t count, loff_t *ppos) |
303 |
size_t count, loff_t *ppos) |
| 302 |
{ |
304 |
{ |
|
|
305 |
loff_t pos = *ppos; |
| 303 |
int i, j, k; |
306 |
int i, j, k; |
| 304 |
char *p; |
307 |
char *p; |
| 305 |
u32 *q; |
308 |
u32 *q; |
| 306 |
void *b; |
309 |
void *b; |
| 307 |
openprom_property *op; |
310 |
openprom_property *op; |
| 308 |
|
311 |
|
| 309 |
if (filp->f_pos >= 0xffffff) |
312 |
if (pos < 0 || pos >= 0xffffff) |
| 310 |
return -EINVAL; |
313 |
return -EINVAL; |
| 311 |
if (!filp->private_data) { |
314 |
if (!filp->private_data) { |
| 312 |
i = property_read (filp, NULL, 0, 0); |
315 |
i = property_read (filp, NULL, 0, 0); |
| 313 |
if (i) |
316 |
if (i) |
| 314 |
return i; |
317 |
return i; |
| 315 |
} |
318 |
} |
| 316 |
k = filp->f_pos; |
319 |
k = pos; |
| 317 |
op = (openprom_property *)filp->private_data; |
320 |
op = (openprom_property *)filp->private_data; |
| 318 |
if (!(op->flag & OPP_STRING)) { |
321 |
if (!(op->flag & OPP_STRING)) { |
| 319 |
u32 *first, *last; |
322 |
u32 *first, *last; |
|
Lines 433-439
Link Here
|
| 433 |
op->len = i; |
436 |
op->len = i; |
| 434 |
} else |
437 |
} else |
| 435 |
op->len = i; |
438 |
op->len = i; |
| 436 |
filp->f_pos += count; |
439 |
pos += count; |
|
|
440 |
*ppos = pos; |
| 437 |
} |
441 |
} |
| 438 |
write_try_string: |
442 |
write_try_string: |
| 439 |
if (!(op->flag & OPP_BINARY)) { |
443 |
if (!(op->flag & OPP_BINARY)) { |
|
Lines 450-456
Link Here
|
| 450 |
op->flag |= OPP_QUOTED; |
454 |
op->flag |= OPP_QUOTED; |
| 451 |
buf++; |
455 |
buf++; |
| 452 |
count--; |
456 |
count--; |
| 453 |
filp->f_pos++; |
457 |
pos++; |
|
|
458 |
*ppos = pos; |
| 454 |
if (!count) { |
459 |
if (!count) { |
| 455 |
op->flag |= OPP_STRING; |
460 |
op->flag |= OPP_STRING; |
| 456 |
return 1; |
461 |
return 1; |
|
Lines 459-467
Link Here
|
| 459 |
op->flag |= OPP_NOTQUOTED; |
464 |
op->flag |= OPP_NOTQUOTED; |
| 460 |
} |
465 |
} |
| 461 |
op->flag |= OPP_STRING; |
466 |
op->flag |= OPP_STRING; |
| 462 |
if (op->alloclen <= count + filp->f_pos) { |
467 |
if (op->alloclen <= count + pos) { |
| 463 |
b = kmalloc (sizeof (openprom_property) |
468 |
b = kmalloc (sizeof (openprom_property) |
| 464 |
+ 2 * (count + filp->f_pos), GFP_KERNEL); |
469 |
+ 2 * (count + pos), GFP_KERNEL); |
| 465 |
if (!b) |
470 |
if (!b) |
| 466 |
return -ENOMEM; |
471 |
return -ENOMEM; |
| 467 |
memcpy (b, filp->private_data, |
472 |
memcpy (b, filp->private_data, |
|
Lines 469-482
Link Here
|
| 469 |
+ strlen (op->name) + op->alloclen); |
474 |
+ strlen (op->name) + op->alloclen); |
| 470 |
memset (((char *)b) + sizeof (openprom_property) |
475 |
memset (((char *)b) + sizeof (openprom_property) |
| 471 |
+ strlen (op->name) + op->alloclen, |
476 |
+ strlen (op->name) + op->alloclen, |
| 472 |
0, 2*(count - filp->f_pos) - op->alloclen); |
477 |
0, 2*(count - pos) - op->alloclen); |
| 473 |
op = (openprom_property *)b; |
478 |
op = (openprom_property *)b; |
| 474 |
op->alloclen = 2*(count + filp->f_pos); |
479 |
op->alloclen = 2*(count + pos); |
| 475 |
b = filp->private_data; |
480 |
b = filp->private_data; |
| 476 |
filp->private_data = (void *)op; |
481 |
filp->private_data = (void *)op; |
| 477 |
kfree (b); |
482 |
kfree (b); |
| 478 |
} |
483 |
} |
| 479 |
p = op->value + filp->f_pos - ((op->flag & OPP_QUOTED) ? 1 : 0); |
484 |
p = op->value + pos - ((op->flag & OPP_QUOTED) ? 1 : 0); |
| 480 |
copy_from_user (p, buf, count); |
485 |
copy_from_user (p, buf, count); |
| 481 |
op->flag |= OPP_DIRTY; |
486 |
op->flag |= OPP_DIRTY; |
| 482 |
for (i = 0; i < count; i++, p++) |
487 |
for (i = 0; i < count; i++, p++) |
|
Lines 486-502
Link Here
|
| 486 |
} |
491 |
} |
| 487 |
if (i < count) { |
492 |
if (i < count) { |
| 488 |
op->len = p - op->value; |
493 |
op->len = p - op->value; |
| 489 |
filp->f_pos += i + 1; |
494 |
pos += i + 1; |
|
|
495 |
*ppos = pos; |
| 490 |
if ((p > op->value) && (op->flag & OPP_QUOTED) |
496 |
if ((p > op->value) && (op->flag & OPP_QUOTED) |
| 491 |
&& (*(p - 1) == '\'')) |
497 |
&& (*(p - 1) == '\'')) |
| 492 |
op->len--; |
498 |
op->len--; |
| 493 |
} else { |
499 |
} else { |
| 494 |
if (p - op->value > op->len) |
500 |
if (p - op->value > op->len) |
| 495 |
op->len = p - op->value; |
501 |
op->len = p - op->value; |
| 496 |
filp->f_pos += count; |
502 |
pos += count; |
|
|
503 |
*ppos = pos; |
| 497 |
} |
504 |
} |
| 498 |
} |
505 |
} |
| 499 |
return filp->f_pos - k; |
506 |
return pos - k; |
| 500 |
} |
507 |
} |
| 501 |
|
508 |
|
| 502 |
int property_release (struct inode *inode, struct file *filp) |
509 |
int property_release (struct inode *inode, struct file *filp) |