hokuto Abe
/
nisiBlutooth
Embed:
(wiki syntax)
Show/hide line numbers
MassStorage.cpp
00001 00002 /* 00003 Copyright (c) 2010 Peter Barrett 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "stdlib.h" 00025 #include "stdio.h" 00026 #include "string.h" 00027 00028 #include "Utils.h" 00029 #include "USBHost.h" 00030 00031 00032 int MassStorage_ReadCapacity(int device, u32* blockCount, u32* blockSize); 00033 int MassStorage_ReadBlock(int device, u32 block, u8* dst); 00034 int MassStorage_WriteBlock(int device, u32 block, const u8* dst); 00035 00036 00037 #define ERR_BAD_CSW_SIGNATURE -200 00038 00039 #define CBW_SIGNATURE 0x43425355 00040 #define CSW_SIGNATURE 0x53425355 00041 00042 // Command Block 00043 typedef struct 00044 { 00045 u32 Signature; 00046 u32 Tag; 00047 u32 TransferLength; 00048 u8 Flags; 00049 u8 LUN; 00050 u8 CBLength; 00051 u8 CB[16]; // only 6 really 00052 } CBW; 00053 00054 // Status block 00055 typedef struct 00056 { 00057 u32 Signature; 00058 u32 Tag; 00059 u32 DataResidue; 00060 u8 Status; 00061 } CSW; 00062 00063 int SCSIRequestSense(int device); 00064 00065 int DoSCSI(int device, const u8* cmd, int cmdLen, int flags, u8* data, u32 transferLen) 00066 { 00067 CBW cbw; 00068 cbw.Signature = CBW_SIGNATURE; 00069 cbw.Tag = 0; 00070 cbw.TransferLength = transferLen; 00071 cbw.Flags = flags; 00072 cbw.LUN = 0; 00073 cbw.CBLength = cmdLen; 00074 memset(cbw.CB,0,sizeof(cbw.CB)); 00075 memcpy(cbw.CB,cmd,cmdLen); 00076 00077 int r; 00078 r = USBBulkTransfer(device,0x01,(u8*)&cbw,31); // Send the command 00079 if (r < 0) 00080 return r; 00081 00082 if (data) 00083 { 00084 r = USBBulkTransfer(device,flags | 1,data,transferLen); 00085 if (r < 0) 00086 return r; 00087 } 00088 00089 CSW csw; 00090 csw.Signature = 0; 00091 r = USBBulkTransfer(device,0x81,(u8*)&csw,13); 00092 if (r < 0) 00093 return r; 00094 00095 if (csw.Signature != CSW_SIGNATURE) 00096 return ERR_BAD_CSW_SIGNATURE; 00097 00098 // ModeSense? 00099 if (csw.Status == 1 && cmd[0] != 3) 00100 return SCSIRequestSense(device); 00101 00102 return csw.Status; 00103 } 00104 00105 int SCSITestUnitReady(int device) 00106 { 00107 u8 cmd[6]; 00108 memset(cmd,0,6); 00109 return DoSCSI(device,cmd,6,DEVICE_TO_HOST,0,0); 00110 } 00111 00112 int SCSIRequestSense(int device) 00113 { 00114 u8 cmd[6] = {0x03,0,0,0,18,0}; 00115 u8 result[18]; 00116 int r = DoSCSI(device,cmd,6,DEVICE_TO_HOST,result,18); 00117 return r; 00118 } 00119 00120 int SCSIInquiry(int device) 00121 { 00122 u8 cmd[6] = {0x12,0,0,0,36,0}; 00123 u8 result[36+2]; 00124 result[36] = '\n'; 00125 result[37] = 0; 00126 int r = DoSCSI(device,cmd,6,DEVICE_TO_HOST,result,36); 00127 if (r == 0) 00128 printf((const char*)result + 8); 00129 return r; 00130 } 00131 00132 int SCSIReadCapacity(int device, u32* blockCount, u32* blockSize) 00133 { 00134 u8 cmd[10] = {0x25,0,0,0,8,0,0,0,0,0}; 00135 u8 result[8]; 00136 *blockSize = 0; 00137 *blockCount = 0; 00138 int r = DoSCSI(device,cmd,10,DEVICE_TO_HOST,result,8); 00139 if (r == 0) 00140 { 00141 *blockCount = BE32(result); 00142 *blockSize = BE32(result+4); 00143 } 00144 return r; 00145 } 00146 00147 int SCSITransfer(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize, int direction) 00148 { 00149 // USB hardware will only do 4k per transfer 00150 while (blockCount*blockSize > 4096) 00151 { 00152 int count = 4096/blockSize; 00153 int r = SCSITransfer(device,blockAddr,count,dst,blockSize,direction); 00154 dst += count*blockSize; 00155 blockAddr += count; 00156 blockCount -= count; 00157 } 00158 00159 u8 cmd[10]; 00160 memset(cmd,0,10); 00161 cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A; 00162 BE32(blockAddr,cmd+2); 00163 BE16(blockCount,cmd+7); 00164 return DoSCSI(device,cmd,10,direction,dst,blockSize*blockCount); 00165 } 00166 00167 int MassStorage_ReadCapacity(int device, u32* blockCount, u32* blockSize) 00168 { 00169 return SCSIReadCapacity(device,blockCount,blockSize); 00170 } 00171 00172 int MassStorage_Read(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize = 512) 00173 { 00174 return SCSITransfer(device,blockAddr,blockCount,dst,blockSize,DEVICE_TO_HOST); 00175 } 00176 00177 int MassStorage_Write(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize = 512) 00178 { 00179 return SCSITransfer(device,blockAddr,blockCount,dst,blockSize,HOST_TO_DEVICE); 00180 }
Generated on Wed Jul 13 2022 17:02:32 by 1.7.2