devfs.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <auth.h>
  4. #include <fcall.h>
  5. #include <thread.h>
  6. #include <9p.h>
  7. #include "flashfs.h"
  8. static char* file;
  9. static int fd;
  10. static uchar *ones;
  11. static int isdev;
  12. struct {
  13. int dfd; /* data */
  14. int cfd; /* control */
  15. } flash;
  16. void
  17. initdata(char *f, int)
  18. {
  19. char err[ERRMAX];
  20. char buf[1024], *fld[8];
  21. int n;
  22. Dir *d;
  23. isdev = 1;
  24. flash.dfd = open(f, ORDWR);
  25. if(flash.dfd < 0){
  26. errstr(err, sizeof err);
  27. if((flash.dfd = create(f, ORDWR, 0666)) >= 0){
  28. fprint(2, "warning: created plain file %s\n", buf);
  29. goto Plain;
  30. }
  31. errstr(err, sizeof err); /* restore open error */
  32. sysfatal("opening %s: %r", f);
  33. }
  34. if(snprint(buf, sizeof buf, "%sctl", f) != strlen(f)+3)
  35. sysfatal("path too long: %s", f);
  36. flash.cfd = open(buf, ORDWR);
  37. if(flash.cfd < 0){
  38. fprint(2, "warning: cannot open %s (%r); assuming plain file\n", buf);
  39. Plain:
  40. isdev = 0;
  41. if(sectsize == 0)
  42. sectsize = 512;
  43. if(nsects == 0){
  44. if((d = dirstat(f)) == nil)
  45. sysfatal("stat %s: %r", f);
  46. nsects = d->length / sectsize;
  47. free(d);
  48. }
  49. ones = emalloc9p(sectsize);
  50. memset(ones, ~0, sectsize);
  51. }else{
  52. n = read(flash.cfd, buf, sizeof(buf)-1);
  53. if(n <= 0)
  54. sysfatal("reading %sctl: %r", f);
  55. buf[n] = 0;
  56. n = tokenize(buf, fld, nelem(fld));
  57. if(n < 7)
  58. sysfatal("bad flash geometry");
  59. nsects = atoi(fld[5]);
  60. sectsize = atoi(fld[6]);
  61. if(nsects < 8)
  62. sysfatal("unreasonable value for nsects: %lud", nsects);
  63. if(sectsize < 512)
  64. sysfatal("unreasonable value for sectsize: %lud", sectsize);
  65. }
  66. }
  67. void
  68. clearsect(int sect)
  69. {
  70. if(isdev==0){
  71. if(pwrite(flash.dfd, ones, sectsize, sect*sectsize) != sectsize)
  72. sysfatal("couldn't erase sector %d: %r", sect);
  73. }else{
  74. if(fprint(flash.cfd, "erase %lud", sect * sectsize) < 0)
  75. sysfatal("couldn't erase sector %d: %r", sect);
  76. }
  77. }
  78. void
  79. readdata(int sect, void *buff, ulong count, ulong off)
  80. {
  81. long n;
  82. ulong m;
  83. m = sect * sectsize + off;
  84. n = pread(flash.dfd, buff, count, m);
  85. if(n < 0)
  86. sysfatal("error reading at %lux: %r", m);
  87. if(n != count)
  88. sysfatal("short read at %lux, %ld instead of %lud\n", m, n, count);
  89. }
  90. int
  91. writedata(int err, int sect, void *buff, ulong count, ulong off)
  92. {
  93. long n;
  94. ulong m;
  95. m = sect*sectsize + off;
  96. n = pwrite(flash.dfd, buff, count, m);
  97. if(n < 0){
  98. if(err)
  99. return 0;
  100. sysfatal("error writing at %lux: %r", m);
  101. }
  102. if(n != count){
  103. if(err)
  104. return 0;
  105. sysfatal("short write at %lud, %ld instead of %lud", m, n, count);
  106. }
  107. return 1;
  108. }