scsi.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. #ifndef MAX_SECTOR_SIZE
  66. #define MAX_SECTOR_SIZE 8192
  67. #endif
  68. #ifndef MIN_SECTOR_SIZE
  69. #define MIN_SECTOR_SIZE 64
  70. #endif
  71. #ifndef SCSI2SD_BUFFER_SIZE
  72. #define SCSI2SD_BUFFER_SIZE (MAX_SECTOR_SIZE * 8)
  73. #endif
  74. // Shadow parameters, possibly not saved to flash yet.
  75. // Set via Mode Select
  76. typedef struct
  77. {
  78. uint16_t bytesPerSector;
  79. } LiveCfg;
  80. typedef struct
  81. {
  82. uint8_t targetId;
  83. const S2S_TargetCfg* cfg;
  84. LiveCfg liveCfg;
  85. ScsiSense sense;
  86. uint16_t unitAttention; // Set to the sense qualifier key to be returned.
  87. uint8_t unitAttentionStop; // Indicates if unit attention has to be stopped.
  88. // Only let the reserved initiator talk to us.
  89. // A 3rd party may be sending the RESERVE/RELEASE commands
  90. int reservedId; // 0 -> 7 if reserved. -1 if not reserved.
  91. int reserverId; // 0 -> 7 if reserved. -1 if not reserved.
  92. uint8_t syncOffset;
  93. uint8_t syncPeriod;
  94. uint8_t started; // Controlled by START STOP UNIT
  95. } TargetState;
  96. typedef struct
  97. {
  98. // TODO reduce this buffer size and add a proper cache
  99. // Must be aligned for DMA
  100. // 65536 bytes is the DMA limit
  101. uint8_t data[SCSI2SD_BUFFER_SIZE];
  102. TargetState targets[S2S_MAX_TARGETS];
  103. TargetState* target;
  104. S2S_BoardCfg boardCfg;
  105. // Set to true (1) if the ATN flag was set, and we need to
  106. // enter the MESSAGE_OUT phase.
  107. int atnFlag;
  108. // Set to true (1) if the RST flag was set.
  109. volatile int resetFlag;
  110. // Set to sel register if the SEL flag was set.
  111. volatile int selFlag;
  112. // Set to true (1) if a parity error was observed.
  113. int parityError;
  114. int phase;
  115. int dataPtr; // Index into data, reset on [re]selection to savedDataPtr
  116. int savedDataPtr; // Index into data, initially 0.
  117. int dataLen;
  118. uint8_t cdb[20]; // command descriptor block
  119. uint8_t cdbLen; // 6, 10, or 12 byte message.
  120. int8_t lun; // Target lun, set by IDENTIFY message.
  121. uint8_t discPriv; // Disconnect priviledge.
  122. uint8_t compatMode; // SCSI_COMPAT_MODE
  123. // Only let the reserved initiator talk to us.
  124. // A 3rd party may be sending the RESERVE/RELEASE commands
  125. int initiatorId; // 0 -> 7. Set during the selection phase.
  126. // SCSI_STATUS value.
  127. // Change to CHECK_CONDITION when setting a SENSE value
  128. uint8_t status;
  129. uint8_t msgIn;
  130. uint8_t msgOut;
  131. void (*postDataOutHook)(void);
  132. uint8_t cmdCount;
  133. uint8_t selCount;
  134. uint8_t rstCount;
  135. uint8_t msgCount;
  136. uint8_t watchdogTick;
  137. uint8_t lastStatus;
  138. uint8_t lastSense;
  139. uint16_t lastSenseASC;
  140. uint8_t minSyncPeriod; // Debug use only.
  141. int needSyncNegotiationAck;
  142. int sdUnderrunCount;
  143. // Estimate of the SCSI host actual speed
  144. uint32_t hostSpeedKBs;
  145. int hostSpeedMeasured;
  146. } ScsiDevice;
  147. typedef enum
  148. {
  149. VENDOR_EXTENSION_OPTICAL_PLEXTOR = 1 << 0,
  150. } VENDOR_EXTENSION_OPTICAL;
  151. extern ScsiDevice scsiDev;
  152. void process_Status(void);
  153. int process_MessageIn(int releaseBusFree);
  154. void enter_BusFree(void);
  155. void scsiInit(void);
  156. void scsiPoll(void);
  157. void scsiDisconnect(void);
  158. int scsiReconnect(void);
  159. // Utility macros, consistent with the Linux Kernel code.
  160. #define likely(x) __builtin_expect(!!(x), 1)
  161. #define unlikely(x) __builtin_expect(!!(x), 0)
  162. //#define likely(x) (x)
  163. //#define unlikely(x) (x)
  164. #endif