ZuluSCSI_log_trace.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // SCSI trace logging
  2. #include "ZuluSCSI_log_trace.h"
  3. #include "ZuluSCSI_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 int g_InByteCount = 0;
  11. static int g_OutByteCount = 0;
  12. static uint16_t g_DataChecksum = 0;
  13. static const char *getCommandName(uint8_t cmd)
  14. {
  15. switch (cmd)
  16. {
  17. case 0x00: return "TestUnitReady";
  18. case 0x01: return "RezeroUnit";
  19. case 0x03: return "RequestSense";
  20. case 0x04: return "FormatUnit";
  21. case 0x08: return "Read6";
  22. case 0x0A: return "Write6";
  23. case 0x0B: return "Seek6";
  24. case 0x0F: return "WriteSectorBuffer";
  25. case 0x12: return "Inquiry";
  26. case 0x15: return "ModeSelect6";
  27. case 0x16: return "Reserve";
  28. case 0x17: return "Release";
  29. case 0x1A: return "ModeSense";
  30. case 0x1B: return "StartStopUnit";
  31. case 0x1C: return "ReceiveDiagnostic";
  32. case 0x1D: return "SendDiagnostic";
  33. case 0x1E: return "PreventAllowMediumRemoval";
  34. case 0x25: return "ReadCapacity";
  35. case 0x28: return "Read10";
  36. case 0x2A: return "Write10";
  37. case 0x2B: return "Seek10";
  38. case 0x2C: return "Erase10";
  39. case 0x2E: return "WriteVerify";
  40. case 0x2F: return "Verify";
  41. case 0x34: return "PreFetch";
  42. case 0x35: return "SynchronizeCache";
  43. case 0x36: return "LockUnlockCache";
  44. case 0x37: return "ReadDefectData";
  45. case 0x3B: return "WriteBuffer";
  46. case 0x3C: return "ReadBuffer";
  47. case 0x43: return "CDROM Read TOC";
  48. case 0x44: return "CDROM Read Header";
  49. case 0x4A: return "GetEventStatusNotification";
  50. case 0x55: return "ModeSelect10";
  51. case 0x5A: return "ModeSense10";
  52. case 0xAC: return "Erase12";
  53. case 0xC0: return "OMTI-5204 DefineFlexibleDiskFormat";
  54. case 0xC2: return "OMTI-5204 AssignDiskParameters";
  55. default: return "Unknown";
  56. }
  57. }
  58. static void printNewPhase(int phase)
  59. {
  60. g_LogData = false;
  61. if (!g_azlog_debug)
  62. {
  63. return;
  64. }
  65. switch(phase)
  66. {
  67. case BUS_FREE:
  68. azdbg("-- BUS_FREE");
  69. break;
  70. case BUS_BUSY:
  71. azdbg("-- BUS_BUSY");
  72. break;
  73. case ARBITRATION:
  74. azdbg("---- ARBITRATION");
  75. break;
  76. case SELECTION:
  77. azdbg("---- SELECTION: ", (int)(*SCSI_STS_SELECTED & 7));
  78. break;
  79. case RESELECTION:
  80. azdbg("---- RESELECTION");
  81. break;
  82. case STATUS:
  83. if (scsiDev.status == GOOD)
  84. {
  85. azdbg("---- STATUS: 0 GOOD");
  86. }
  87. else if (scsiDev.status == CHECK_CONDITION && scsiDev.target)
  88. {
  89. azdbg("---- STATUS: 2 CHECK_CONDITION, sense ", (uint32_t)scsiDev.target->sense.asc);
  90. }
  91. else
  92. {
  93. azdbg("---- STATUS: ", (int)scsiDev.status);
  94. }
  95. break;
  96. case COMMAND:
  97. g_LogData = true;
  98. break;
  99. case DATA_IN:
  100. if (scsiDev.target->syncOffset > 0)
  101. azdbg("---- DATA_IN, syncOffset ", (int)scsiDev.target->syncOffset,
  102. " syncPeriod ", (int)scsiDev.target->syncPeriod);
  103. else
  104. azdbg("---- DATA_IN");
  105. break;
  106. case DATA_OUT:
  107. if (scsiDev.target->syncOffset > 0)
  108. azdbg("---- DATA_OUT, syncOffset ", (int)scsiDev.target->syncOffset,
  109. " syncPeriod ", (int)scsiDev.target->syncPeriod);
  110. else
  111. azdbg("---- DATA_OUT");
  112. break;
  113. case MESSAGE_IN:
  114. azdbg("---- MESSAGE_IN");
  115. g_LogData = true;
  116. break;
  117. case MESSAGE_OUT:
  118. azdbg("---- MESSAGE_OUT");
  119. g_LogData = true;
  120. break;
  121. default:
  122. azdbg("---- PHASE: ", phase);
  123. break;
  124. }
  125. }
  126. void scsiLogPhaseChange(int new_phase)
  127. {
  128. static int old_scsi_id = 0;
  129. static int old_phase = BUS_FREE;
  130. static int old_sync_period = 0;
  131. if (new_phase != old_phase)
  132. {
  133. if (old_phase == DATA_IN || old_phase == DATA_OUT)
  134. {
  135. azdbg("---- Total IN: ", g_InByteCount, " OUT: ", g_OutByteCount, " CHECKSUM: ", (int)g_DataChecksum);
  136. }
  137. g_InByteCount = g_OutByteCount = 0;
  138. g_DataChecksum = 0;
  139. if (old_phase >= 0 &&
  140. old_scsi_id == scsiDev.target->targetId &&
  141. old_sync_period != scsiDev.target->syncPeriod)
  142. {
  143. // Add a log message when negotiated synchronous speed changes.
  144. int syncper = scsiDev.target->syncPeriod;
  145. int syncoff = scsiDev.target->syncOffset;
  146. int mbyte_per_s = (1000 + syncper * 2) / (syncper * 4);
  147. azlog("SCSI ID ", (int)scsiDev.target->targetId,
  148. " negotiated synchronous mode ", mbyte_per_s, " MB/s ",
  149. "(period 4x", syncper, " ns, offset ", syncoff, " bytes)");
  150. }
  151. printNewPhase(new_phase);
  152. old_phase = new_phase;
  153. old_sync_period = scsiDev.target->syncPeriod;
  154. old_scsi_id = scsiDev.target->targetId;
  155. }
  156. }
  157. void scsiLogDataIn(const uint8_t *buf, uint32_t length)
  158. {
  159. if (g_LogData)
  160. {
  161. azdbg("------ IN: ", bytearray(buf, length));
  162. }
  163. if (g_azlog_debug)
  164. {
  165. // BSD checksum algorithm
  166. for (uint32_t i = 0; i < length; i++)
  167. {
  168. g_DataChecksum = (g_DataChecksum >> 1) + ((g_DataChecksum & 1) << 15);
  169. g_DataChecksum += buf[i];
  170. }
  171. }
  172. g_InByteCount += length;
  173. }
  174. void scsiLogDataOut(const uint8_t *buf, uint32_t length)
  175. {
  176. if (buf == scsiDev.cdb)
  177. {
  178. azdbg("---- COMMAND: ", getCommandName(buf[0]));
  179. }
  180. if (g_LogData)
  181. {
  182. azdbg("------ OUT: ", bytearray(buf, length));
  183. }
  184. if (g_azlog_debug)
  185. {
  186. // BSD checksum algorithm
  187. for (uint32_t i = 0; i < length; i++)
  188. {
  189. g_DataChecksum = (g_DataChecksum >> 1) + ((g_DataChecksum & 1) << 15);
  190. g_DataChecksum += buf[i];
  191. }
  192. }
  193. g_OutByteCount += length;
  194. }