dd0c33a391bba50029f695dbb79c6b8aeb6a9e7a
[SCSI2SD-V6.git] / software / SCSI2SD / src / 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 // Set this to true to log SCSI commands and status information via
21 // USB HID packets.  The can be captured and viewed in wireshark.
22 // For windows users, capture using USBPcap http://desowin.org/usbpcap/
23 #define MM_DEBUG 1
24
25 #include "geometry.h"
26 #include "sense.h"
27
28 typedef enum
29 {
30         // internal bits
31         __scsiphase_msg = 1,
32         __scsiphase_cd = 2,
33         __scsiphase_io = 4,
34
35         BUS_FREE = -1,
36         BUS_BUSY = -2,
37         ARBITRATION = -3,
38         SELECTION = -4,
39         RESELECTION = -5,
40         STATUS = __scsiphase_cd | __scsiphase_io,
41         COMMAND = __scsiphase_cd,
42         DATA_IN = __scsiphase_io,
43         DATA_OUT = 0,
44         MESSAGE_IN = __scsiphase_msg | __scsiphase_cd | __scsiphase_io,
45         MESSAGE_OUT = __scsiphase_msg | __scsiphase_cd
46 } SCSI_PHASE;
47
48 typedef enum
49 {
50         GOOD = 0,
51         CHECK_CONDITION = 2,
52         BUSY = 0x8,
53         INTERMEDIATE = 0x10,
54         CONFLICT = 0x18
55 } SCSI_STATUS;
56
57 typedef enum
58 {
59         MSG_COMMAND_COMPLETE = 0,
60         MSG_REJECT = 0x7,
61         MSG_LINKED_COMMAND_COMPLETE = 0x0A,
62         MSG_LINKED_COMMAND_COMPLETE_WITH_FLAG = 0x0B
63 } SCSI_MESSAGE;
64
65 // Maximum value for bytes-per-sector.
66 #define MAX_SECTOR_SIZE 2048
67 #define MIN_SECTOR_SIZE 64
68
69 typedef struct
70 {
71         uint8_t scsiIdMask;
72
73         // Set to true (1) if the ATN flag was set, and we need to
74         // enter the MESSAGE_OUT phase.
75         volatile int atnFlag;
76
77         // Set to true (1) if the RST flag was set.
78         volatile int resetFlag;
79
80         // Set to true (1) if a parity error was observed.
81         int parityError;
82
83         int phase;
84
85         uint8 data[MAX_SECTOR_SIZE];
86         int dataPtr; // Index into data, reset on [re]selection to savedDataPtr
87         int savedDataPtr; // Index into data, initially 0.
88         int dataLen;
89
90         uint8 cdb[12]; // command descriptor block
91         uint8 cdbLen; // 6, 10, or 12 byte message.
92
93         // Only let the reserved initiator talk to us.
94         // A 3rd party may be sending the RESERVE/RELEASE commands
95         int initiatorId; // 0 -> 7. Set during the selection phase.
96         int reservedId; // 0 -> 7 if reserved. -1 if not reserved.
97         int reserverId; // 0 -> 7 if reserved. -1 if not reserved.
98
99         // SCSI_STATUS value.
100         // Change to SCSI_STATUS_CHECK_CONDITION when setting a SENSE value
101         uint8 status;
102
103         ScsiSense sense;
104
105         uint16 unitAttention; // Set to the sense qualifier key to be returned.
106
107         uint8 msgIn;
108         uint8 msgOut;
109
110         void (*postDataOutHook)(void);
111
112 #ifdef MM_DEBUG
113         uint8 cmdCount;
114         uint8 selCount;
115         uint8 rstCount;
116         uint8 msgCount;
117         uint8 watchdogTick;
118         uint8 lastStatus;
119         uint8 lastSense;
120 #endif
121 } ScsiDevice;
122
123 extern ScsiDevice scsiDev;
124
125 void scsiInit(void);
126 void scsiPoll(void);
127
128
129 #endif