Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BSP_DISCO_F746NG_patch mbed-rtos mbed
usbh_msc_scsi.c
00001 /** 00002 ****************************************************************************** 00003 * @file usbh_msc_scsi.c 00004 * @author MCD Application Team 00005 * @version V3.2.2 00006 * @date 07-July-2015 00007 * @brief This file implements the SCSI commands 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> 00012 * 00013 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00014 * You may not use this file except in compliance with the License. 00015 * You may obtain a copy of the License at: 00016 * 00017 * http://www.st.com/software_license_agreement_liberty_v2 00018 * 00019 * Unless required by applicable law or agreed to in writing, software 00020 * distributed under the License is distributed on an "AS IS" BASIS, 00021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00022 * See the License for the specific language governing permissions and 00023 * limitations under the License. 00024 * 00025 ****************************************************************************** 00026 */ 00027 00028 /* Includes ------------------------------------------------------------------*/ 00029 #include "usbh_msc.h" 00030 #include "usbh_msc_scsi.h" 00031 #include "usbh_msc_bot.h" 00032 00033 00034 /** @addtogroup USBH_LIB 00035 * @{ 00036 */ 00037 00038 /** @addtogroup USBH_CLASS 00039 * @{ 00040 */ 00041 00042 /** @addtogroup USBH_MSC_CLASS 00043 * @{ 00044 */ 00045 00046 /** @defgroup USBH_MSC_SCSI 00047 * @brief This file includes the mass storage related functions 00048 * @{ 00049 */ 00050 00051 00052 /** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions 00053 * @{ 00054 */ 00055 00056 /** 00057 * @} 00058 */ 00059 00060 /** @defgroup USBH_MSC_SCSI_Private_Defines 00061 * @{ 00062 */ 00063 /** 00064 * @} 00065 */ 00066 00067 /** @defgroup USBH_MSC_SCSI_Private_Macros 00068 * @{ 00069 */ 00070 /** 00071 * @} 00072 */ 00073 00074 00075 /** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes 00076 * @{ 00077 */ 00078 /** 00079 * @} 00080 */ 00081 00082 00083 /** @defgroup USBH_MSC_SCSI_Exported_Variables 00084 * @{ 00085 */ 00086 00087 /** 00088 * @} 00089 */ 00090 00091 00092 /** @defgroup USBH_MSC_SCSI_Private_Functions 00093 * @{ 00094 */ 00095 00096 00097 /** 00098 * @brief USBH_MSC_SCSI_TestUnitReady 00099 * Issue TestUnitReady command. 00100 * @param phost: Host handle 00101 * @param lun: Logical Unit Number 00102 * @retval USBH Status 00103 */ 00104 USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady (USBH_HandleTypeDef *phost, 00105 uint8_t lun) 00106 { 00107 USBH_StatusTypeDef error = USBH_FAIL ; 00108 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00109 00110 switch(MSC_Handle->hbot.cmd_state) 00111 { 00112 case BOT_CMD_SEND: 00113 00114 /*Prepare the CBW and relevent field*/ 00115 MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY; 00116 MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT; 00117 MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; 00118 00119 USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); 00120 MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_TEST_UNIT_READY; 00121 00122 MSC_Handle->hbot.state = BOT_SEND_CBW; 00123 MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; 00124 error = USBH_BUSY; 00125 break; 00126 00127 case BOT_CMD_WAIT: 00128 error = USBH_MSC_BOT_Process(phost, lun); 00129 break; 00130 00131 default: 00132 break; 00133 } 00134 00135 return error; 00136 } 00137 00138 /** 00139 * @brief USBH_MSC_SCSI_ReadCapacity 00140 * Issue Read Capacity command. 00141 * @param phost: Host handle 00142 * @param lun: Logical Unit Number 00143 * @param capacity: pointer to the capacity structure 00144 * @retval USBH Status 00145 */ 00146 USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity (USBH_HandleTypeDef *phost, 00147 uint8_t lun, 00148 SCSI_CapacityTypeDef *capacity) 00149 { 00150 USBH_StatusTypeDef error = USBH_BUSY ; 00151 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00152 00153 switch(MSC_Handle->hbot.cmd_state) 00154 { 00155 case BOT_CMD_SEND: 00156 00157 /*Prepare the CBW and relevent field*/ 00158 MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_READ_CAPACITY10; 00159 MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN; 00160 MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; 00161 00162 USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); 00163 MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ_CAPACITY10; 00164 00165 MSC_Handle->hbot.state = BOT_SEND_CBW; 00166 00167 MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; 00168 MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data; 00169 error = USBH_BUSY; 00170 break; 00171 00172 case BOT_CMD_WAIT: 00173 00174 error = USBH_MSC_BOT_Process(phost, lun); 00175 00176 if(error == USBH_OK) 00177 { 00178 /*assign the capacity*/ 00179 capacity->block_nbr = MSC_Handle->hbot.pbuf[3] | (MSC_Handle->hbot.pbuf[2] << 8) |\ 00180 (MSC_Handle->hbot.pbuf[1] << 16) | (MSC_Handle->hbot.pbuf[0] << 24); 00181 00182 /*assign the page length*/ 00183 capacity->block_size = MSC_Handle->hbot.pbuf[7] | (MSC_Handle->hbot.pbuf[6] << 8); 00184 } 00185 break; 00186 00187 default: 00188 break; 00189 } 00190 00191 return error; 00192 } 00193 00194 /** 00195 * @brief USBH_MSC_SCSI_Inquiry 00196 * Issue Inquiry command. 00197 * @param phost: Host handle 00198 * @param lun: Logical Unit Number 00199 * @param capacity: pointer to the inquiry structure 00200 * @retval USBH Status 00201 */ 00202 USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry (USBH_HandleTypeDef *phost, 00203 uint8_t lun, 00204 SCSI_StdInquiryDataTypeDef *inquiry) 00205 { 00206 USBH_StatusTypeDef error = USBH_FAIL ; 00207 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00208 switch(MSC_Handle->hbot.cmd_state) 00209 { 00210 case BOT_CMD_SEND: 00211 00212 /*Prepare the CBW and relevent field*/ 00213 MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_INQUIRY; 00214 MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN; 00215 MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; 00216 00217 USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_LENGTH); 00218 MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_INQUIRY; 00219 MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5); 00220 MSC_Handle->hbot.cbw.field.CB[2] = 0; 00221 MSC_Handle->hbot.cbw.field.CB[3] = 0; 00222 MSC_Handle->hbot.cbw.field.CB[4] = 0x24; 00223 MSC_Handle->hbot.cbw.field.CB[5] = 0; 00224 00225 MSC_Handle->hbot.state = BOT_SEND_CBW; 00226 00227 MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; 00228 MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data; 00229 error = USBH_BUSY; 00230 break; 00231 00232 case BOT_CMD_WAIT: 00233 00234 error = USBH_MSC_BOT_Process(phost, lun); 00235 00236 if(error == USBH_OK) 00237 { 00238 USBH_memset(inquiry, 0, sizeof(SCSI_StdInquiryDataTypeDef)); 00239 /*assign Inquiry Data */ 00240 inquiry->DeviceType = MSC_Handle->hbot.pbuf[0] & 0x1F; 00241 inquiry->PeripheralQualifier = MSC_Handle->hbot.pbuf[0] >> 5; 00242 inquiry->RemovableMedia = (MSC_Handle->hbot.pbuf[1] & 0x80)== 0x80; 00243 USBH_memcpy (inquiry->vendor_id, &MSC_Handle->hbot.pbuf[8], 8); 00244 USBH_memcpy (inquiry->product_id, &MSC_Handle->hbot.pbuf[16], 16); 00245 USBH_memcpy (inquiry->revision_id, &MSC_Handle->hbot.pbuf[32], 4); 00246 } 00247 break; 00248 00249 default: 00250 break; 00251 } 00252 00253 return error; 00254 } 00255 00256 /** 00257 * @brief USBH_MSC_SCSI_RequestSense 00258 * Issue RequestSense command. 00259 * @param phost: Host handle 00260 * @param lun: Logical Unit Number 00261 * @param capacity: pointer to the sense data structure 00262 * @retval USBH Status 00263 */ 00264 USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense (USBH_HandleTypeDef *phost, 00265 uint8_t lun, 00266 SCSI_SenseTypeDef *sense_data) 00267 { 00268 USBH_StatusTypeDef error = USBH_FAIL ; 00269 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00270 00271 switch(MSC_Handle->hbot.cmd_state) 00272 { 00273 case BOT_CMD_SEND: 00274 00275 /*Prepare the CBW and relevent field*/ 00276 MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_REQUEST_SENSE; 00277 MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN; 00278 MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; 00279 00280 USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); 00281 MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_REQUEST_SENSE; 00282 MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5); 00283 MSC_Handle->hbot.cbw.field.CB[2] = 0; 00284 MSC_Handle->hbot.cbw.field.CB[3] = 0; 00285 MSC_Handle->hbot.cbw.field.CB[4] = DATA_LEN_REQUEST_SENSE; 00286 MSC_Handle->hbot.cbw.field.CB[5] = 0; 00287 00288 MSC_Handle->hbot.state = BOT_SEND_CBW; 00289 MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; 00290 MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data; 00291 error = USBH_BUSY; 00292 break; 00293 00294 case BOT_CMD_WAIT: 00295 00296 error = USBH_MSC_BOT_Process(phost, lun); 00297 00298 if(error == USBH_OK) 00299 { 00300 sense_data->key = MSC_Handle->hbot.pbuf[2] & 0x0F; 00301 sense_data->asc = MSC_Handle->hbot.pbuf[12]; 00302 sense_data->ascq = MSC_Handle->hbot.pbuf[13]; 00303 } 00304 break; 00305 00306 default: 00307 break; 00308 } 00309 00310 return error; 00311 } 00312 00313 /** 00314 * @brief USBH_MSC_SCSI_Write 00315 * Issue write10 command. 00316 * @param phost: Host handle 00317 * @param lun: Logical Unit Number 00318 * @param address: sector address 00319 * @param pbuf: pointer to data 00320 * @param length: number of sector to write 00321 * @retval USBH Status 00322 */ 00323 USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost, 00324 uint8_t lun, 00325 uint32_t address, 00326 uint8_t *pbuf, 00327 uint32_t length) 00328 { 00329 USBH_StatusTypeDef error = USBH_FAIL ; 00330 00331 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00332 00333 switch(MSC_Handle->hbot.cmd_state) 00334 { 00335 case BOT_CMD_SEND: 00336 00337 /*Prepare the CBW and relevent field*/ 00338 MSC_Handle->hbot.cbw.field.DataTransferLength = length * 512; 00339 MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT; 00340 MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; 00341 00342 USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); 00343 MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_WRITE10; 00344 00345 /*logical block address*/ 00346 MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t*)&address)[3]); 00347 MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t*)&address)[2]); 00348 MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]); 00349 MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]); 00350 00351 00352 /*Transfer length */ 00353 MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ; 00354 MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ; 00355 00356 00357 MSC_Handle->hbot.state = BOT_SEND_CBW; 00358 MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; 00359 MSC_Handle->hbot.pbuf = pbuf; 00360 error = USBH_BUSY; 00361 break; 00362 00363 case BOT_CMD_WAIT: 00364 error = USBH_MSC_BOT_Process(phost, lun); 00365 break; 00366 00367 default: 00368 break; 00369 } 00370 00371 return error; 00372 } 00373 00374 /** 00375 * @brief USBH_MSC_SCSI_Read 00376 * Issue Read10 command. 00377 * @param phost: Host handle 00378 * @param lun: Logical Unit Number 00379 * @param address: sector address 00380 * @param pbuf: pointer to data 00381 * @param length: number of sector to read 00382 * @retval USBH Status 00383 */ 00384 USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost, 00385 uint8_t lun, 00386 uint32_t address, 00387 uint8_t *pbuf, 00388 uint32_t length) 00389 { 00390 USBH_StatusTypeDef error = USBH_FAIL ; 00391 MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; 00392 00393 switch(MSC_Handle->hbot.cmd_state) 00394 { 00395 case BOT_CMD_SEND: 00396 00397 /*Prepare the CBW and relevent field*/ 00398 MSC_Handle->hbot.cbw.field.DataTransferLength = length * 512; 00399 MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN; 00400 MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; 00401 00402 USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); 00403 MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ10; 00404 00405 /*logical block address*/ 00406 MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t*)&address)[3]); 00407 MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t*)&address)[2]); 00408 MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]); 00409 MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]); 00410 00411 00412 /*Transfer length */ 00413 MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ; 00414 MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ; 00415 00416 00417 MSC_Handle->hbot.state = BOT_SEND_CBW; 00418 MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; 00419 MSC_Handle->hbot.pbuf = pbuf; 00420 error = USBH_BUSY; 00421 break; 00422 00423 case BOT_CMD_WAIT: 00424 error = USBH_MSC_BOT_Process(phost, lun); 00425 break; 00426 00427 default: 00428 break; 00429 } 00430 00431 return error; 00432 } 00433 00434 00435 /** 00436 * @} 00437 */ 00438 00439 /** 00440 * @} 00441 */ 00442 00443 /** 00444 * @} 00445 */ 00446 00447 /** 00448 * @} 00449 */ 00450 00451 /** 00452 * @} 00453 */ 00454 00455 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 00456 00457 00458
Generated on Tue Jul 12 2022 14:58:25 by
1.7.2