devfs.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <auth.h>
  12. #include <fcall.h>
  13. #include <thread.h>
  14. #include <9p.h>
  15. #include "flashfs.h"
  16. static uint8_t *ones;
  17. static int isdev;
  18. struct {
  19. int dfd; /* data */
  20. int cfd; /* control */
  21. } flash;
  22. void
  23. initdata(char *f, int i)
  24. {
  25. char err[ERRMAX];
  26. char buf[1024], *fld[8];
  27. int n;
  28. Dir *d;
  29. isdev = 1;
  30. flash.dfd = open(f, ORDWR);
  31. if(flash.dfd < 0){
  32. errstr(err, sizeof err);
  33. if((flash.dfd = create(f, ORDWR, 0666)) >= 0){
  34. fprint(2, "warning: created plain file %s\n", buf);
  35. goto Plain;
  36. }
  37. errstr(err, sizeof err); /* restore open error */
  38. sysfatal("opening %s: %r", f);
  39. }
  40. if(snprint(buf, sizeof buf, "%sctl", f) != strlen(f)+3)
  41. sysfatal("path too long: %s", f);
  42. flash.cfd = open(buf, ORDWR);
  43. if(flash.cfd < 0){
  44. fprint(2, "warning: cannot open %s (%r); assuming plain file\n", buf);
  45. Plain:
  46. isdev = 0;
  47. if(sectsize == 0)
  48. sectsize = 512;
  49. if(nsects == 0){
  50. if((d = dirstat(f)) == nil)
  51. sysfatal("stat %s: %r", f);
  52. nsects = d->length / sectsize;
  53. free(d);
  54. }
  55. ones = emalloc9p(sectsize);
  56. memset(ones, ~0, sectsize);
  57. }else{
  58. n = read(flash.cfd, buf, sizeof(buf)-1);
  59. if(n <= 0)
  60. sysfatal("reading %sctl: %r", f);
  61. buf[n] = 0;
  62. n = tokenize(buf, fld, nelem(fld));
  63. if(n < 7)
  64. sysfatal("bad flash geometry");
  65. nsects = atoi(fld[5]);
  66. sectsize = atoi(fld[6]);
  67. if(nsects < 8)
  68. sysfatal("unreasonable value for nsects: %lu", nsects);
  69. if(sectsize < 512)
  70. sysfatal("unreasonable value for sectsize: %lu", sectsize);
  71. }
  72. }
  73. void
  74. clearsect(int sect)
  75. {
  76. if(isdev==0){
  77. if(pwrite(flash.dfd, ones, sectsize, sect*sectsize) != sectsize)
  78. sysfatal("couldn't erase sector %d: %r", sect);
  79. }else{
  80. if(fprint(flash.cfd, "erase %lu", sect * sectsize) < 0)
  81. sysfatal("couldn't erase sector %d: %r", sect);
  82. }
  83. }
  84. void
  85. readdata(int sect, void *buff, uint32_t count, uint32_t off)
  86. {
  87. int32_t n;
  88. uint32_t m;
  89. m = sect * sectsize + off;
  90. n = pread(flash.dfd, buff, count, m);
  91. if(n < 0)
  92. sysfatal("error reading at %lx: %r", m);
  93. if(n != count)
  94. sysfatal("short read at %lx, %ld instead of %lu", m, n, count);
  95. }
  96. int
  97. writedata(int err, int sect, void *buff, uint32_t count, uint32_t off)
  98. {
  99. int32_t n;
  100. uint32_t m;
  101. m = sect*sectsize + off;
  102. n = pwrite(flash.dfd, buff, count, m);
  103. if(n < 0){
  104. if(err)
  105. return 0;
  106. sysfatal("error writing at %lx: %r", m);
  107. }
  108. if(n != count){
  109. if(err)
  110. return 0;
  111. sysfatal("short write at %lu, %ld instead of %lu", m, n, count);
  112. }
  113. return 1;
  114. }