cdaudio.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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 <bio.h>
  12. #include <disk.h>
  13. #include "scsireq.h"
  14. extern Biobuf bout;
  15. int32_t
  16. SRcdpause(ScsiReq *rp, int resume)
  17. {
  18. uint8_t cmd[10];
  19. memset(cmd, 0, sizeof(cmd));
  20. cmd[0] = ScmdCDpause;
  21. cmd[8] = resume;
  22. rp->cmd.p = cmd;
  23. rp->cmd.count = sizeof(cmd);
  24. rp->data.p = cmd;
  25. rp->data.count = 0;
  26. rp->data.write = 1;
  27. return SRrequest(rp);
  28. }
  29. int32_t
  30. SRcdstop(ScsiReq *rp)
  31. {
  32. uint8_t cmd[10];
  33. memset(cmd, 0, sizeof(cmd));
  34. cmd[0] = ScmdCDstop;
  35. rp->cmd.p = cmd;
  36. rp->cmd.count = sizeof(cmd);
  37. rp->data.p = cmd;
  38. rp->data.count = 0;
  39. rp->data.write = 1;
  40. return SRrequest(rp);
  41. }
  42. static int32_t
  43. _SRcdplay(ScsiReq *rp, int32_t lba, int32_t length)
  44. {
  45. uint8_t cmd[12];
  46. memset(cmd, 0, sizeof(cmd));
  47. cmd[0] = ScmdCDplay;
  48. cmd[2] = lba>>24;
  49. cmd[3] = lba>>16;
  50. cmd[4] = lba>>8;
  51. cmd[5] = lba;
  52. cmd[6] = length>>24;
  53. cmd[7] = length>>16;
  54. cmd[8] = length>>8;
  55. cmd[9] = length;
  56. rp->cmd.p = cmd;
  57. rp->cmd.count = sizeof(cmd);
  58. rp->data.p = cmd;
  59. rp->data.count = 0;
  60. rp->data.write = 1;
  61. return SRrequest(rp);
  62. }
  63. static struct {
  64. int trackno;
  65. int32_t lba;
  66. int32_t length;
  67. } tracks[100];
  68. static int ntracks;
  69. int32_t
  70. SRcdplay(ScsiReq *rp, int raw, int32_t start, int32_t length)
  71. {
  72. uint8_t d[100*8+4], *p;
  73. int lba, n, tdl;
  74. if(raw || start == 0)
  75. return _SRcdplay(rp, start, length);
  76. ntracks = 0;
  77. if(SRTOC(rp, d, sizeof(d), 0, 0) == -1){
  78. if(rp->status == STok)
  79. Bprint(&bout, "\t(probably empty)\n");
  80. return -1;
  81. }
  82. tdl = (d[0]<<8)|d[1];
  83. for(p = &d[4], n = tdl-2; n; n -= 8, p += 8){
  84. tracks[ntracks].trackno = p[2];
  85. lba = (p[4]<<24)|(p[5]<<16)|(p[6]<<8)|p[7];
  86. tracks[ntracks].lba = lba;
  87. if(ntracks > 0)
  88. tracks[ntracks-1].length = lba-tracks[ntracks-1].lba;
  89. ntracks++;
  90. }
  91. if(ntracks > 0)
  92. tracks[ntracks-1].length = 0xFFFFFFFF;
  93. for(n = 0; n < ntracks; n++){
  94. if(start != tracks[n].trackno)
  95. continue;
  96. return _SRcdplay(rp, tracks[n].lba, tracks[n].length);
  97. }
  98. return -1;
  99. }
  100. int32_t
  101. SRcdload(ScsiReq *rp, int load, int slot)
  102. {
  103. uint8_t cmd[12];
  104. memset(cmd, 0, sizeof(cmd));
  105. cmd[0] = ScmdCDload;
  106. if(load)
  107. cmd[4] = 0x03;
  108. else
  109. cmd[4] = 0x02;
  110. cmd[8] = slot;
  111. rp->cmd.p = cmd;
  112. rp->cmd.count = sizeof(cmd);
  113. rp->data.p = cmd;
  114. rp->data.count = 0;
  115. rp->data.write = 1;
  116. return SRrequest(rp);
  117. }
  118. int32_t
  119. SRcdstatus(ScsiReq *rp, uint8_t *list, int nbytes)
  120. {
  121. uint8_t cmd[12];
  122. memset(cmd, 0, sizeof(cmd));
  123. cmd[0] = ScmdCDstatus;
  124. cmd[8] = nbytes>>8;
  125. cmd[9] = nbytes;
  126. rp->cmd.p = cmd;
  127. rp->cmd.count = sizeof(cmd);
  128. rp->data.p = list;
  129. rp->data.count = nbytes;
  130. rp->data.write = 0;
  131. return SRrequest(rp);
  132. }
  133. int32_t
  134. SRgetconf(ScsiReq *rp, uint8_t *list, int nbytes)
  135. {
  136. uint8_t cmd[10];
  137. memset(cmd, 0, sizeof(cmd));
  138. cmd[0] = Scmdgetconf;
  139. cmd[7] = nbytes>>8;
  140. cmd[8] = nbytes;
  141. rp->cmd.p = cmd;
  142. rp->cmd.count = sizeof(cmd);
  143. rp->data.p = list;
  144. rp->data.count = nbytes;
  145. rp->data.write = 0;
  146. return SRrequest(rp);
  147. }