sdbios.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * boot driver for BIOS devices with partitions
  3. * devbios must be called first
  4. */
  5. #include "u.h"
  6. #include "lib.h"
  7. #include "mem.h"
  8. #include "dat.h"
  9. #include "fns.h"
  10. #include "io.h"
  11. #include "ureg.h"
  12. #include "error.h"
  13. #include "sd.h"
  14. #include "fs.h"
  15. long biosread(Fs *, void *, long);
  16. vlong biosseek(Fs *fs, vlong off);
  17. extern SDifc sdbiosifc;
  18. extern int onlybios0, biosinited;
  19. int
  20. biosverify(SDunit* )
  21. {
  22. if (onlybios0 || !biosinited)
  23. return 0;
  24. return 1;
  25. }
  26. int
  27. biosonline(SDunit* unit)
  28. {
  29. if (onlybios0 || !biosinited || !unit)
  30. return 0;
  31. unit->sectors = 1UL << 30; /* a bunch */
  32. unit->secsize = 512; /* conventional */
  33. return 1;
  34. }
  35. static int
  36. biosrio(SDreq* r)
  37. {
  38. int nb;
  39. long got;
  40. vlong len, off;
  41. uchar *p;
  42. Fs fs; /* just for fs->dev, which is zero */
  43. if (onlybios0 || !biosinited)
  44. return SDeio;
  45. /*
  46. * Most SCSI commands can be passed unchanged except for
  47. * the padding on the end. The few which require munging
  48. * are not used internally. Mode select/sense(6) could be
  49. * converted to the 10-byte form but it's not worth the
  50. * effort. Read/write(6) are easy.
  51. */
  52. r->rlen = 0;
  53. r->status = SDok;
  54. switch(r->cmd[0]){
  55. case 0x08: /* read */
  56. case 0x28: /* read */
  57. if (r->cmd[0] == 0x08)
  58. panic("biosrio: 0x08 read op\n");
  59. off = r->cmd[2]<<24 | r->cmd[3]<<16 | r->cmd[4]<<8 | r->cmd[5];
  60. nb = r->cmd[7]<<8 | r->cmd[8]; /* often 4 */
  61. USED(nb); /* is nb*512 == r->dlen? */
  62. memset(&fs, 0, sizeof fs);
  63. biosseek(&fs, off*512);
  64. got = biosread(&fs, r->data, r->dlen);
  65. if (got < 0)
  66. r->status = SDeio;
  67. else
  68. r->rlen = got;
  69. break;
  70. case 0x0A: /* write */
  71. case 0x2A: /* write */
  72. r->status = SDeio; /* boot programs don't write */
  73. break;
  74. case 0x25: /* read capacity */
  75. /*
  76. * Read capacity returns the LBA of the last sector.
  77. */
  78. len = r->unit->sectors - 1;
  79. p = r->data;
  80. *p++ = len>>24;
  81. *p++ = len>>16;
  82. *p++ = len>>8;
  83. *p++ = len;
  84. len = r->unit->secsize;
  85. *p++ = len>>24;
  86. *p++ = len>>16;
  87. *p++ = len>>8;
  88. *p = len;
  89. r->data = (char *)r->data + 8;
  90. return SDok;
  91. case 0x9E: /* long read capacity */
  92. /*
  93. * Read capacity returns the LBA of the last sector.
  94. */
  95. len = r->unit->sectors - 1;
  96. p = r->data;
  97. *p++ = len>>56;
  98. *p++ = len>>48;
  99. *p++ = len>>40;
  100. *p++ = len>>32;
  101. *p++ = len>>24;
  102. *p++ = len>>16;
  103. *p++ = len>>8;
  104. *p++ = len;
  105. len = r->unit->secsize;
  106. *p++ = len>>24;
  107. *p++ = len>>16;
  108. *p++ = len>>8;
  109. *p = len;
  110. r->data = (char *)r->data + 8;
  111. return SDok;
  112. /* ignore others */
  113. }
  114. return r->status;
  115. }
  116. SDev*
  117. biosid(SDev* sdev)
  118. {
  119. for (; sdev; sdev = sdev->next)
  120. if (sdev->ifc == &sdbiosifc)
  121. sdev->idno = 'B';
  122. return sdev;
  123. }
  124. static SDev*
  125. biospnp(void)
  126. {
  127. SDev *sdev;
  128. /* 9pxeload can't use bios int 13 calls; they wedge the machine */
  129. if (pxe || getconf("*nobiosload") != nil || onlybios0 || !biosinited)
  130. return nil;
  131. if((sdev = malloc(sizeof(SDev))) != nil) {
  132. sdev->ifc = &sdbiosifc;
  133. sdev->index = -1;
  134. sdev->nunit = 1;
  135. }
  136. return sdev;
  137. }
  138. SDifc sdbiosifc = {
  139. "bios", /* name */
  140. biospnp, /* pnp */
  141. nil, /* legacy */
  142. biosid, /* id */
  143. nil, /* enable */
  144. nil, /* disable */
  145. biosverify, /* verify */
  146. biosonline, /* online */
  147. biosrio, /* rio */
  148. nil, /* rctl */
  149. nil, /* wctl */
  150. scsibio, /* bio */
  151. };