BlueSCSI_log_trace.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // SCSI trace logging
  2. #include "BlueSCSI_log_trace.h"
  3. #include "BlueSCSI_log.h"
  4. #include <scsi2sd.h>
  5. extern "C" {
  6. #include <scsi.h>
  7. #include <scsiPhy.h>
  8. }
  9. static bool g_LogData = false;
  10. static bool g_LogInitiatorCommand = false;
  11. static int g_InByteCount = 0;
  12. static int g_OutByteCount = 0;
  13. static uint16_t g_DataChecksum = 0;
  14. static const char *getCommandName(uint8_t cmd)
  15. {
  16. switch (cmd)
  17. {
  18. case 0x00: return "TestUnitReady";
  19. case 0x01: return "RezeroUnit";
  20. case 0x03: return "RequestSense";
  21. case 0x04: return "FormatUnit";
  22. case 0x08: return "Read6";
  23. case 0x0A: return "Write6";
  24. case 0x0B: return "Seek6";
  25. case 0x0F: return "WriteSectorBuffer";
  26. case 0x11: return "Space";
  27. case 0x12: return "Inquiry";
  28. case 0x15: return "ModeSelect6";
  29. case 0x16: return "Reserve";
  30. case 0x17: return "Release";
  31. case 0x1A: return "ModeSense";
  32. case 0x1B: return "StartStopUnit";
  33. case 0x1C: return "ReceiveDiagnostic";
  34. case 0x1D: return "SendDiagnostic";
  35. case 0x1E: return "PreventAllowMediumRemoval";
  36. case 0x25: return "ReadCapacity";
  37. case 0x28: return "Read10";
  38. case 0x2A: return "Write10";
  39. case 0x2B: return "Seek10";
  40. case 0x2C: return "Erase10";
  41. case 0x2E: return "WriteVerify";
  42. case 0x2F: return "Verify";
  43. case 0x34: return "PreFetch";
  44. case 0x35: return "SynchronizeCache";
  45. case 0x36: return "LockUnlockCache";
  46. case 0x37: return "ReadDefectData";
  47. case 0x3B: return "WriteBuffer";
  48. case 0x3C: return "ReadBuffer";
  49. case 0x43: return "CDROM Read TOC";
  50. case 0x44: return "CDROM Read Header";
  51. case 0x4A: return "GetEventStatusNotification";
  52. case 0x51: return "CDROM ReadDiscInformation";
  53. case 0x45: return "CDROM PlayAudio10";
  54. case 0xA5: return "CDROM PlayAudio12";
  55. case 0x47: return "CDROM PlayAudioMSF";
  56. case 0x48: return "CDROM PauseResume";
  57. case 0xBB: return "CDROM SetCDSpeed";
  58. case 0xBD: return "CDROM MechanismStatus";
  59. case 0xBE: return "ReadCD";
  60. case 0xB9: return "ReadCDMSF";
  61. case 0x55: return "ModeSelect10";
  62. case 0x5A: return "ModeSense10";
  63. case 0xAC: return "Erase12";
  64. case 0xA8: return "Read12";
  65. case 0xC0: return "OMTI-5204 DefineFlexibleDiskFormat";
  66. case 0xC2: return "OMTI-5204 AssignDiskParameters";
  67. default: return "Unknown";
  68. }
  69. }
  70. static void printNewPhase(int phase, bool initiator = false)
  71. {
  72. g_LogData = false;
  73. g_LogInitiatorCommand = false;
  74. if (!g_log_debug)
  75. {
  76. return;
  77. }
  78. switch(phase)
  79. {
  80. case BUS_FREE:
  81. debuglog("-- BUS_FREE");
  82. break;
  83. case BUS_BUSY:
  84. debuglog("-- BUS_BUSY");
  85. break;
  86. case ARBITRATION:
  87. debuglog("---- ARBITRATION");
  88. break;
  89. case SELECTION:
  90. if (initiator)
  91. debuglog("---- SELECTION");
  92. else
  93. debuglog("---- SELECTION: ", (int)(*SCSI_STS_SELECTED & 7));
  94. break;
  95. case RESELECTION:
  96. debuglog("---- RESELECTION");
  97. break;
  98. case STATUS:
  99. if (initiator)
  100. {
  101. debuglog("---- STATUS");
  102. g_LogData = true;
  103. }
  104. else if (scsiDev.status == GOOD)
  105. {
  106. debuglog("---- STATUS: 0 GOOD");
  107. }
  108. else if (scsiDev.status == CHECK_CONDITION && scsiDev.target)
  109. {
  110. debuglog("---- STATUS: 2 CHECK_CONDITION, sense ", (uint32_t)scsiDev.target->sense.asc);
  111. }
  112. else
  113. {
  114. debuglog("---- STATUS: ", (int)scsiDev.status);
  115. }
  116. break;
  117. case COMMAND:
  118. g_LogInitiatorCommand = initiator;
  119. g_LogData = true;
  120. break;
  121. case DATA_IN:
  122. if (!initiator && scsiDev.target->syncOffset > 0)
  123. debuglog("---- DATA_IN, syncOffset ", (int)scsiDev.target->syncOffset,
  124. " syncPeriod ", (int)scsiDev.target->syncPeriod);
  125. else
  126. debuglog("---- DATA_IN");
  127. break;
  128. case DATA_OUT:
  129. if (!initiator && scsiDev.target->syncOffset > 0)
  130. debuglog("---- DATA_OUT, syncOffset ", (int)scsiDev.target->syncOffset,
  131. " syncPeriod ", (int)scsiDev.target->syncPeriod);
  132. else
  133. debuglog("---- DATA_OUT");
  134. break;
  135. case MESSAGE_IN:
  136. debuglog("---- MESSAGE_IN");
  137. g_LogData = true;
  138. break;
  139. case MESSAGE_OUT:
  140. debuglog("---- MESSAGE_OUT");
  141. g_LogData = true;
  142. break;
  143. default:
  144. debuglog("---- PHASE: ", phase);
  145. break;
  146. }
  147. }
  148. void scsiLogPhaseChange(int new_phase)
  149. {
  150. static int old_scsi_id = 0;
  151. static int old_phase = BUS_FREE;
  152. static int old_sync_period = 0;
  153. if (new_phase != old_phase)
  154. {
  155. if (old_phase == DATA_IN || old_phase == DATA_OUT)
  156. {
  157. debuglog("---- Total IN: ", g_InByteCount, " OUT: ", g_OutByteCount, " CHECKSUM: ", (int)g_DataChecksum);
  158. }
  159. g_InByteCount = g_OutByteCount = 0;
  160. g_DataChecksum = 0;
  161. if (old_phase >= 0 &&
  162. scsiDev.target != NULL &&
  163. old_scsi_id == scsiDev.target->targetId &&
  164. old_sync_period != scsiDev.target->syncPeriod)
  165. {
  166. // Add a log message when negotiated synchronous speed changes.
  167. int syncper = scsiDev.target->syncPeriod;
  168. int syncoff = scsiDev.target->syncOffset;
  169. if (syncper > 0)
  170. {
  171. int mbyte_per_s = (1000 + syncper * 2) / (syncper * 4);
  172. log("SCSI ID ", (int)scsiDev.target->targetId,
  173. " negotiated synchronous mode ", mbyte_per_s, " MB/s ",
  174. "(period 4x", syncper, " ns, offset ", syncoff, " bytes)");
  175. }
  176. else
  177. {
  178. log("SCSI ID ", (int)scsiDev.target->targetId,
  179. " negotiated asynchronous mode ",
  180. "(period 4x", syncper, " ns, offset ", syncoff, " bytes)");
  181. }
  182. }
  183. printNewPhase(new_phase);
  184. old_phase = new_phase;
  185. old_sync_period = scsiDev.target->syncPeriod;
  186. old_scsi_id = scsiDev.target->targetId;
  187. }
  188. }
  189. void scsiLogInitiatorPhaseChange(int new_phase)
  190. {
  191. static int old_phase = BUS_FREE;
  192. if (new_phase != old_phase)
  193. {
  194. if (old_phase == DATA_IN || old_phase == DATA_OUT)
  195. {
  196. debuglog("---- Total IN: ", g_InByteCount, " OUT: ", g_OutByteCount, " CHECKSUM: ", (int)g_DataChecksum);
  197. }
  198. g_InByteCount = g_OutByteCount = 0;
  199. g_DataChecksum = 0;
  200. printNewPhase(new_phase, true);
  201. old_phase = new_phase;
  202. }
  203. }
  204. void scsiLogDataIn(const uint8_t *buf, uint32_t length)
  205. {
  206. if (g_LogData)
  207. {
  208. debuglog("------ IN: ", bytearray(buf, length));
  209. }
  210. if (g_log_debug)
  211. {
  212. // BSD checksum algorithm
  213. for (uint32_t i = 0; i < length; i++)
  214. {
  215. g_DataChecksum = (g_DataChecksum >> 1) + ((g_DataChecksum & 1) << 15);
  216. g_DataChecksum += buf[i];
  217. }
  218. }
  219. g_InByteCount += length;
  220. }
  221. void scsiLogDataOut(const uint8_t *buf, uint32_t length)
  222. {
  223. if (buf == scsiDev.cdb || g_LogInitiatorCommand)
  224. {
  225. debuglog("---- COMMAND: ", getCommandName(buf[0]));
  226. }
  227. if (g_LogData)
  228. {
  229. debuglog("------ OUT: ", bytearray(buf, length));
  230. }
  231. if (g_log_debug)
  232. {
  233. // BSD checksum algorithm
  234. for (uint32_t i = 0; i < length; i++)
  235. {
  236. g_DataChecksum = (g_DataChecksum >> 1) + ((g_DataChecksum & 1) << 15);
  237. g_DataChecksum += buf[i];
  238. }
  239. }
  240. g_OutByteCount += length;
  241. }