Initial support for cross-compiling scsi2sd-util6 with osxcross on Linux
[SCSI2SD-V6.git] / src / firmware / scsi.h
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
20 #include "geometry.h"
21 #include "sense.h"
22
23 #include <stdint.h>
24
25 typedef enum
26 {
27         // internal bits
28         __scsiphase_msg = 1,
29         __scsiphase_cd = 2,
30         __scsiphase_io = 4,
31
32         BUS_FREE = -1,
33         BUS_BUSY = -2,
34         ARBITRATION = -3,
35         SELECTION = -4,
36         RESELECTION = -5,
37         STATUS = __scsiphase_cd | __scsiphase_io,
38         COMMAND = __scsiphase_cd,
39         DATA_IN = __scsiphase_io,
40         DATA_OUT = 0,
41         MESSAGE_IN = __scsiphase_msg | __scsiphase_cd | __scsiphase_io,
42         MESSAGE_OUT = __scsiphase_msg | __scsiphase_cd
43 } SCSI_PHASE;
44
45 typedef enum
46 {
47         GOOD = 0,
48         CHECK_CONDITION = 2,
49         BUSY = 0x8,
50         INTERMEDIATE = 0x10,
51         CONFLICT = 0x18
52 } SCSI_STATUS;
53
54 typedef enum
55 {
56         MSG_COMMAND_COMPLETE = 0,
57         MSG_REJECT = 0x7,
58         MSG_LINKED_COMMAND_COMPLETE = 0x0A,
59         MSG_LINKED_COMMAND_COMPLETE_WITH_FLAG = 0x0B
60 } SCSI_MESSAGE;
61
62 typedef enum
63 {
64         COMPAT_UNKNOWN,
65         COMPAT_SCSI1,
66
67         // Messages are being used, yet SCSI 2 mode is disabled.
68         // This impacts interpretation of INQUIRY commands.
69         COMPAT_SCSI2_DISABLED,
70
71         COMPAT_SCSI2
72 } SCSI_COMPAT_MODE;
73
74 // Maximum value for bytes-per-sector.
75 #define MAX_SECTOR_SIZE 8192
76 #define MIN_SECTOR_SIZE 64
77
78 // Shadow parameters, possibly not saved to flash yet.
79 // Set via Mode Select
80 typedef struct
81 {
82         uint16_t bytesPerSector;
83 } LiveCfg;
84
85 typedef struct
86 {
87         uint8_t targetId;
88
89         const S2S_TargetCfg* cfg;
90
91         LiveCfg liveCfg;
92
93         ScsiSense sense;
94
95         uint16_t unitAttention; // Set to the sense qualifier key to be returned.
96
97         // Only let the reserved initiator talk to us.
98         // A 3rd party may be sending the RESERVE/RELEASE commands
99         int reservedId; // 0 -> 7 if reserved. -1 if not reserved.
100         int reserverId; // 0 -> 7 if reserved. -1 if not reserved.
101
102         uint8_t syncOffset;
103         uint8_t syncPeriod;
104 } TargetState;
105
106 typedef struct
107 {
108         // TODO reduce this buffer size and add a proper cache
109         // Must be aligned for DMA
110         // 65536 bytes is the DMA limit
111         uint8_t data[MAX_SECTOR_SIZE * 8];
112
113         TargetState targets[S2S_MAX_TARGETS];
114         TargetState* target;
115         S2S_BoardCfg boardCfg;
116
117
118         // Set to true (1) if the ATN flag was set, and we need to
119         // enter the MESSAGE_OUT phase.
120         int atnFlag;
121
122         // Set to true (1) if the RST flag was set.
123         volatile int resetFlag;
124
125         // Set to sel register if the SEL flag was set.
126         volatile int selFlag;
127
128         // Set to true (1) if a parity error was observed.
129         int parityError;
130
131         int phase;
132
133         int dataPtr; // Index into data, reset on [re]selection to savedDataPtr
134         int savedDataPtr; // Index into data, initially 0.
135         int dataLen;
136
137         uint8_t cdb[12]; // command descriptor block
138         uint8_t cdbLen; // 6, 10, or 12 byte message.
139         int8_t lun; // Target lun, set by IDENTIFY message.
140         uint8_t discPriv; // Disconnect priviledge.
141         uint8_t compatMode; // SCSI_COMPAT_MODE
142
143         // Only let the reserved initiator talk to us.
144         // A 3rd party may be sending the RESERVE/RELEASE commands
145         int initiatorId; // 0 -> 7. Set during the selection phase.
146
147         // SCSI_STATUS value.
148         // Change to CHECK_CONDITION when setting a SENSE value
149         uint8_t status;
150
151         uint8_t msgIn;
152         uint8_t msgOut;
153
154         void (*postDataOutHook)(void);
155
156         uint8_t cmdCount;
157         uint8_t selCount;
158         uint8_t rstCount;
159         uint8_t msgCount;
160         uint8_t watchdogTick;
161         uint8_t lastStatus;
162         uint8_t lastSense;
163         uint16_t lastSenseASC;
164         uint8_t minSyncPeriod; // Debug use only.
165
166         int needSyncNegotiationAck;
167         int sdUnderrunCount;
168
169         // Estimate of the SCSI host actual speed
170         uint32_t hostSpeedKBs;
171         int hostSpeedMeasured;
172 } ScsiDevice;
173
174 extern ScsiDevice scsiDev;
175
176 void process_Status(void);
177 int process_MessageIn(int releaseBusFree);
178 void enter_BusFree(void);
179
180 void scsiInit(void);
181 void scsiPoll(void);
182 void scsiDisconnect(void);
183 int scsiReconnect(void);
184
185
186 // Utility macros, consistent with the Linux Kernel code.
187 #define likely(x)       __builtin_expect(!!(x), 1)
188 #define unlikely(x)     __builtin_expect(!!(x), 0)
189 //#define likely(x)       (x)
190 //#define unlikely(x)     (x)
191 #endif