1 /*!
2  * @file        usbd_msc_scsi.h
3  *
4  * @brief       MSC scsi
5  *
6  * @version     V1.0.1
7  *
8  * @date        2022-09-20
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be useful and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 /* Define to prevent recursive inclusion */
27 #ifndef __USBD_MSC_SCSI_H_
28 #define __USBD_MSC_SCSI_H_
29 
30 /* Includes */
31 #include "usbd_core.h"
32 
33 /** @addtogroup USB_Driver_Library USB Driver Library
34   @{
35 */
36 
37 /** @addtogroup Core_Device Core Device
38   @{
39 */
40 
41 /** @addtogroup Class
42   @{
43 */
44 
45 /** @addtogroup MSC_SCSI
46   @{
47 */
48 
49 /** @defgroup MSC_SCSI_Macros Macros
50   @{
51 */
52 
53 #define SCSI_SENSE_LIST_NUMBER                      4
54 #define SCSI_INQUIRY_LENGTH                         36
55 
56 /* SCSI Commands */
57 #define SCSI_CMD_FORMAT_UNIT                        ((uint8_t)0x04)
58 #define SCSI_CMD_INQUIRY                            ((uint8_t)0x12)
59 #define SCSI_CMD_MODE_SELECT_6                      ((uint8_t)0x15)
60 #define SCSI_CMD_MODE_SELECT_10                     ((uint8_t)0x55)
61 #define SCSI_CMD_MODE_SENSE_6                       ((uint8_t)0x1A)
62 #define SCSI_CMD_MODE_SENSE_10                      ((uint8_t)0x5A)
63 #define SCSI_CMD_ALLOW_MEDIUM_REMOVAL               ((uint8_t)0x1E)
64 #define SCSI_CMD_READ_6                             ((uint8_t)0x08)
65 #define SCSI_CMD_READ_10                            ((uint8_t)0x28)
66 #define SCSI_CMD_READ_12                            ((uint8_t)0xA8)
67 #define SCSI_CMD_READ_16                            ((uint8_t)0x88)
68 
69 #define SCSI_CMD_READ_CAPACITY_10                   ((uint8_t)0x25)
70 #define SCSI_CMD_READ_CAPACITY_16                   ((uint8_t)0x9E)
71 
72 #define SCSI_CMD_REQUEST_SENSE                      ((uint8_t)0x03)
73 #define SCSI_CMD_START_STOP_UNIT                    ((uint8_t)0x1B)
74 #define SCSI_CMD_TEST_UNIT_READY                    ((uint8_t)0x00)
75 #define SCSI_CMD_WRITE6                             ((uint8_t)0x0A)
76 #define SCSI_CMD_WRITE10                            ((uint8_t)0x2A)
77 #define SCSI_CMD_WRITE12                            ((uint8_t)0xAA)
78 #define SCSI_CMD_WRITE16                            ((uint8_t)0x8A)
79 
80 #define SCSI_CMD_VERIFY_10                          ((uint8_t)0x2F)
81 #define SCSI_CMD_VERIFY_12                          ((uint8_t)0xAF)
82 #define SCSI_CMD_VERIFY_16                          ((uint8_t)0x8F)
83 
84 #define SCSI_CMD_SEND_DIAGNOSTIC                    ((uint8_t)0x1D)
85 #define SCSI_CMD_READ_FORMAT_CAPACITIES             ((uint8_t)0x23)
86 
87 #define SCSI_ASC_INVALID_CDB                         0x20
88 #define SCSI_ASC_INVALID_FIELED_IN_COMMAND           0x24
89 #define SCSI_ASC_PARAMETER_LIST_LENGTH_ERROR         0x1A
90 #define SCSI_ASC_INVALID_FIELD_IN_PARAMETER_LIST     0x26
91 #define SCSI_ASC_ADDRESS_OUT_OF_RANGE                0x21
92 #define SCSI_ASC_MEDIUM_NOT_PRESENT                  0x3A
93 #define SCSI_ASC_MEDIUM_HAVE_CHANGED                 0x28
94 #define SCSI_ASC_WRITE_PROTECTED                     0x27
95 #define SCSI_ASC_UNRECOVERED_READ_ERROR              0x11
96 #define SCSI_ASC_WRITE_FAULT                         0x03
97 
98 #define SCSI_READ_FORMAT_CAPACITY_DATA_LEN           0x0C
99 #define SCSI_READ_CAPACITY10_DATA_LEN                0x08
100 #define SCSI_MODE_SENSE10_DATA_LEN                   0x08
101 #define SCSI_MODE_SENSE6_DATA_LEN                    0x04
102 #define SCSI_REQUEST_SENSE_DATA_LEN                  0x12
103 #define SCSI_STANDARD_INQUIRY_DATA_LEN               0x24
104 #define SCSI_BLKVFY                                  0x04
105 
106 /**@} end of group MSC_SCSI_Macros */
107 
108 /** @defgroup MSC_SCSI_Enumerations Enumerations
109   @{
110 */
111 
112 /**
113  * @brief   SCSI function status
114  */
115 typedef enum
116 {
117     SCSI_FAIL,
118     SCSI_OK,
119 } SCSI_STATUS_T;
120 
121 /**
122  * @brief   SCSI Sense Key
123  */
124 typedef enum
125 {
126     SCSI_SKEY_NO_SENSE,
127     SCSI_SKEY_RECOVERED_ERROR,
128     SCSI_SKEY_NOT_READY,
129     SCSI_SKEY_MEDIUM_ERROR,
130     SCSI_SKEY_HARDWARE_ERROR,
131     SCSI_SKEY_ILLEGAL_REQUEST,
132     SCSI_SKEY_UNIT_ATTENTION,
133     SCSI_SKEY_DATA_PROTECT,
134     SCSI_SKEY_BLANK_CHECK,
135     SCSI_SKEY_VENDOR_SPECIFIC,
136     SCSI_SKEY_COPY_ABORTED,
137     SCSI_SKEY_ABORTED_COMMAND,
138     SCSI_SKEY_VOLUME_OVERFLOW = 13,
139     SCSI_SKEY_MISCOMPARE      = 14
140 } SCSI_SKEY_T;
141 
142 /**@} end of group MSC_SCSI_Enumerations */
143 
144 /** @defgroup MSC_SCSI_Structures Structures
145   @{
146 */
147 
148 /**
149  * @brief   SCSI Sense
150  */
151 typedef struct
152 {
153     uint8_t sensekey;
154     uint8_t ASC;
155     uint8_t ASCQ;
156 } SCSI_Sense_T;
157 
158 /**@} end of group MSC_SCSI_Structures */
159 
160 /** @defgroup MSC_SCSI_Variables Variables
161   @{
162 */
163 
164 extern SCSI_Sense_T g_scsiSense[SCSI_SENSE_LIST_NUMBER];
165 extern uint8_t g_senseTxCnt;
166 extern uint8_t g_sensePutCnt;
167 
168 /**@} end of group MSC_SCSI_Variables */
169 
170 /** @defgroup MSC_SCSI_Functions Functions
171   @{
172 */
173 
174 uint8_t SCSI_CmdHandler(uint8_t lun, uint8_t* cmd);
175 void   SCSI_PutSenseCode(uint8_t lun, uint8_t sKey, uint8_t ASC, uint8_t ASCQ);
176 
177 #endif
178 
179 /**@} end of group MSC_SCSI_Functions */
180 /**@} end of group MSC_SCSI */
181 /**@} end of group Class */
182 /**@} end of group Core_Device */
183 /**@} end of group USB_Driver_Library */
184