scsi.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
  2. //
  3. // This file is part of SCSI2SD.
  4. //
  5. // SCSI2SD is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // SCSI2SD is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
  17. #ifndef SCSI_H
  18. #define SCSI_H
  19. #include "geometry.h"
  20. #include "sense.h"
  21. #include <stdint.h>
  22. typedef enum
  23. {
  24. // internal bits
  25. __scsiphase_msg = 1,
  26. __scsiphase_cd = 2,
  27. __scsiphase_io = 4,
  28. BUS_FREE = -1,
  29. BUS_BUSY = -2,
  30. ARBITRATION = -3,
  31. SELECTION = -4,
  32. RESELECTION = -5,
  33. STATUS = __scsiphase_cd | __scsiphase_io,
  34. COMMAND = __scsiphase_cd,
  35. DATA_IN = __scsiphase_io,
  36. DATA_OUT = 0,
  37. MESSAGE_IN = __scsiphase_msg | __scsiphase_cd | __scsiphase_io,
  38. MESSAGE_OUT = __scsiphase_msg | __scsiphase_cd
  39. } SCSI_PHASE;
  40. typedef enum
  41. {
  42. GOOD = 0,
  43. CHECK_CONDITION = 2,
  44. BUSY = 0x8,
  45. INTERMEDIATE = 0x10,
  46. CONFLICT = 0x18
  47. } SCSI_STATUS;
  48. typedef enum
  49. {
  50. MSG_COMMAND_COMPLETE = 0,
  51. MSG_REJECT = 0x7,
  52. MSG_LINKED_COMMAND_COMPLETE = 0x0A,
  53. MSG_LINKED_COMMAND_COMPLETE_WITH_FLAG = 0x0B
  54. } SCSI_MESSAGE;
  55. typedef enum
  56. {
  57. COMPAT_UNKNOWN,
  58. COMPAT_SCSI1,
  59. // Messages are being used, yet SCSI 2 mode is disabled.
  60. // This impacts interpretation of INQUIRY commands.
  61. COMPAT_SCSI2_DISABLED,
  62. COMPAT_SCSI2
  63. } SCSI_COMPAT_MODE;
  64. // Maximum value for bytes-per-sector.
  65. #define MAX_SECTOR_SIZE 8192
  66. #define MIN_SECTOR_SIZE 64
  67. // Shadow parameters, possibly not saved to flash yet.
  68. // Set via Mode Select
  69. typedef struct
  70. {
  71. uint16_t bytesPerSector;
  72. } LiveCfg;
  73. typedef struct
  74. {
  75. uint8_t targetId;
  76. const S2S_TargetCfg* cfg;
  77. LiveCfg liveCfg;
  78. ScsiSense sense;
  79. uint16_t unitAttention; // Set to the sense qualifier key to be returned.
  80. // Only let the reserved initiator talk to us.
  81. // A 3rd party may be sending the RESERVE/RELEASE commands
  82. int reservedId; // 0 -> 7 if reserved. -1 if not reserved.
  83. int reserverId; // 0 -> 7 if reserved. -1 if not reserved.
  84. uint8_t syncOffset;
  85. uint8_t syncPeriod;
  86. uint8_t started; // Controlled by START STOP UNIT
  87. } TargetState;
  88. typedef struct
  89. {
  90. // TODO reduce this buffer size and add a proper cache
  91. // Must be aligned for DMA
  92. // 65536 bytes is the DMA limit
  93. uint8_t data[MAX_SECTOR_SIZE * 8];
  94. TargetState targets[S2S_MAX_TARGETS];
  95. TargetState* target;
  96. S2S_BoardCfg boardCfg;
  97. // Set to true (1) if the ATN flag was set, and we need to
  98. // enter the MESSAGE_OUT phase.
  99. int atnFlag;
  100. // Set to true (1) if the RST flag was set.
  101. volatile int resetFlag;
  102. // Set to sel register if the SEL flag was set.
  103. volatile int selFlag;
  104. // Set to true (1) if a parity error was observed.
  105. int parityError;
  106. int phase;
  107. int dataPtr; // Index into data, reset on [re]selection to savedDataPtr
  108. int savedDataPtr; // Index into data, initially 0.
  109. int dataLen;
  110. uint8_t cdb[12]; // command descriptor block
  111. uint8_t cdbLen; // 6, 10, or 12 byte message.
  112. int8_t lun; // Target lun, set by IDENTIFY message.
  113. uint8_t discPriv; // Disconnect priviledge.
  114. uint8_t compatMode; // SCSI_COMPAT_MODE
  115. // Only let the reserved initiator talk to us.
  116. // A 3rd party may be sending the RESERVE/RELEASE commands
  117. int initiatorId; // 0 -> 7. Set during the selection phase.
  118. // SCSI_STATUS value.
  119. // Change to CHECK_CONDITION when setting a SENSE value
  120. uint8_t status;
  121. uint8_t msgIn;
  122. uint8_t msgOut;
  123. void (*postDataOutHook)(void);
  124. uint8_t cmdCount;
  125. uint8_t selCount;
  126. uint8_t rstCount;
  127. uint8_t msgCount;
  128. uint8_t watchdogTick;
  129. uint8_t lastStatus;
  130. uint8_t lastSense;
  131. uint16_t lastSenseASC;
  132. uint8_t minSyncPeriod; // Debug use only.
  133. int needSyncNegotiationAck;
  134. int sdUnderrunCount;
  135. // Estimate of the SCSI host actual speed
  136. uint32_t hostSpeedKBs;
  137. int hostSpeedMeasured;
  138. } ScsiDevice;
  139. extern ScsiDevice scsiDev;
  140. void process_Status(void);
  141. int process_MessageIn(int releaseBusFree);
  142. void enter_BusFree(void);
  143. void scsiInit(void);
  144. void scsiPoll(void);
  145. void scsiDisconnect(void);
  146. int scsiReconnect(void);
  147. // Utility macros, consistent with the Linux Kernel code.
  148. #define likely(x) __builtin_expect(!!(x), 1)
  149. #define unlikely(x) __builtin_expect(!!(x), 0)
  150. //#define likely(x) (x)
  151. //#define unlikely(x) (x)
  152. #endif