3 #USB Mass Storage Emulator
5 #with thanks to Brandon Wilson and his Linky project.
12 from GoodFETMAXUSB import *;
14 class GoodFETMAXUSBMass(GoodFETMAXUSBDevice):
15 """This emulates a USB Mass Storage device."""
17 def getSectorData(self,lba):
18 """Overload this to return data from a given 512-byte sector."""
19 print "You forgot to overload getSectorData(). Returning something neighborly.";
21 0xE9, 0x86, 0x00, 0x0A, 0x47, 0x6F, 0x6F, 0x64, 0x44, 0x69, 0x73, 0x6B, 0x20, 0x30, 0x2E, 0x30,
22 0x31, 0x0A, 0x0D, 0x62, 0x79, 0x20, 0x54, 0x72, 0x61, 0x76, 0x69, 0x73, 0x20, 0x47, 0x6F, 0x6F,
23 0x64, 0x73, 0x70, 0x65, 0x65, 0x64, 0x0A, 0x0A, 0x0D, 0x00, 0x59, 0x6F, 0x75, 0x20, 0x68, 0x61,
24 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6E, 0x20, 0x65, 0x61, 0x74, 0x65, 0x6E, 0x20, 0x62, 0x79,
25 0x20, 0x61, 0x20, 0x67, 0x72, 0x75, 0x65, 0x2E, 0x20, 0x20, 0x53, 0x6F, 0x72, 0x72, 0x79, 0x2E,
26 0x0A, 0x0D, 0x00, 0x31, 0x29, 0x20, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x6B, 0x65,
27 0x72, 0x6E, 0x65, 0x6C, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x64, 0x69, 0x73, 0x6B, 0x2E, 0x0A,
28 0x0D, 0x00, 0x32, 0x29, 0x20, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x6B,
29 0x65, 0x72, 0x6E, 0x65, 0x6C, 0x2E, 0x0A, 0x0D, 0x00, 0xBE, 0x03, 0x7C, 0xE8, 0x41, 0x00, 0xE8,
30 0x7B, 0x00, 0x31, 0xC0, 0x30, 0xD2, 0xCD, 0x13, 0x0F, 0x82, 0xE8, 0x00, 0xBE, 0x53, 0x7C, 0xE8,
31 0x2E, 0x00, 0xB8, 0xE0, 0x07, 0x8E, 0xC0, 0x31, 0xDB, 0xB8, 0x10, 0x02, 0xB5, 0x00, 0xB1, 0x02,
32 0xB6, 0x00, 0xB2, 0x00, 0xCD, 0x13, 0x0F, 0x82, 0xCA, 0x00, 0xB8, 0x00, 0x7E, 0x89, 0xC6, 0xE8,
33 0x7C, 0x00, 0xBE, 0x72, 0x7C, 0xE8, 0x08, 0x00, 0xEA, 0x00, 0x00, 0xE0, 0x07, 0xE8, 0xB4, 0x00,
34 0xAC, 0x3C, 0x00, 0x74, 0x06, 0xB4, 0x0E, 0xCD, 0x10, 0xEB, 0xF5, 0xC3, 0x30, 0x78, 0x00, 0x20,
35 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x6F, 0x66, 0x20, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x20,
36 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x2E, 0x0A, 0x0D, 0x00, 0x53, 0x65, 0x67, 0x6D,
37 0x65, 0x6E, 0x74, 0x73, 0x3A, 0x20, 0x00, 0x2C, 0x20, 0x00, 0x0A, 0x0D, 0x00, 0xBE, 0xDC, 0x7C,
38 0xE8, 0xBD, 0xFF, 0xE8, 0x63, 0x00, 0xE8, 0x07, 0x00, 0xBE, 0xDF, 0x7C, 0xE8, 0xB1, 0xFF, 0xC3,
39 0x89, 0xC3, 0xC1, 0xE8, 0x0C, 0xE8, 0x39, 0x00, 0x89, 0xD8, 0xC1, 0xE8, 0x08, 0xE8, 0x31, 0x00,
40 0x89, 0xD8, 0xC1, 0xE8, 0x04, 0xE8, 0x29, 0x00, 0x89, 0xD8, 0xE8, 0x24, 0x00, 0xC3, 0x31, 0xC9,
41 0xAD, 0xE8, 0xDC, 0xFF, 0xE8, 0x2C, 0x00, 0x83, 0xC1, 0x02, 0x81, 0xF9, 0x00, 0x02, 0x75, 0xF0,
42 0xC3, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45,
43 0x46, 0x50, 0x56, 0x83, 0xE0, 0x0F, 0x05, 0x51, 0x7D, 0x89, 0xC6, 0xAC, 0xB4, 0x0E, 0xCD, 0x10,
44 0x5E, 0x58, 0xC3, 0xB8, 0x20, 0x0E, 0xCD, 0x10, 0xC3, 0x31, 0xC0, 0xCD, 0x12, 0x72, 0x05, 0x85,
45 0xC0, 0x74, 0x01, 0xC3, 0xBE, 0x2A, 0x7C, 0xE8, 0x46, 0xFF, 0xEB, 0xFE, 0xEA, 0x00, 0x00, 0xFF,
46 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA
55 def putSectorData(self,lba,block):
56 """Overload this to write data to a given 512-byte sector."""
61 """Initialize a USB Mass Storage device."""
62 self.usb_disconnect();
68 """Main loop of the USB Mass Storage emulator."""
69 print "Starting a Mass Storage device. This doesn't work yet.";
73 """Handle USB Enumeration"""
75 #Grab the SETUP packet from the buffer.
76 SUD=self.readbytes(rSUDFIFO,8);
78 #Parse the SETUP packet
79 print "Handling a setup packet of %s" % self.setup2str(SUD);
80 setuptype=(ord(SUD[bmRequestType])&0x60);
82 self.std_request(SUD);
84 self.class_request(SUD);
86 self.vendor_request(SUD);
88 print "Unknown bmRequestType=0x%02x." % ord(SUD[bmRequestType])
90 def class_request(self,SUD):
91 """Handle a class request."""
92 requesttype=ord(SUD[bmRequestType]);
93 request=ord(SUD[bRequest]);
94 if requesttype==0xA1 and request==0xFE:
95 print "Reporting 0 as the maximum LUN.";
96 #This is a Get Max LUN request.
97 #Return 1-byte maximum Logical Unit Number
98 self.wreg(rEP0FIFO,0x00); # Just one LUN.
99 self.wregAS(rEP0BC,1); # ARM and fire!
100 return; #Don't stall.
101 if requesttype==0x21 and request==0xff:
102 print "Received BBB reset."
103 self.wregAS(rEP0BC,0); # ARM and fire!
104 return; #Don't stall.
105 print "Stalling an unknown class request: %s" % self.setup2str(SUD);
107 def vendor_request(self,SUD):
108 """Handle a vendor request."""
109 request=ord(SUD[bRequest]);
110 print "Why the hell is there a vendor request?";
111 #self.wreg(rEP0FIFO,0);
112 self.wregAS(rEP0BC,0);
113 def std_request(self,SUD):
114 """Handles a standard setup request."""
115 setuptype=ord(SUD[bRequest]);
116 if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
117 #elif setuptype==SR_SET_FEATURE: self.feature(1);
118 elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
119 elif setuptype==SR_GET_STATUS: self.get_status(SUD);
120 elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
121 elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
123 #print "Stalling Unknown standard setup request type %02x" % setuptype;
124 #self.STALL_EP0(SUD);
125 print "Accepting unknown standard setup request type %02x" % setuptype;
126 self.wregAS(rEP0BC,0);
128 def get_interface(self,SUD):
129 """Handles a setup request for SR_GET_INTERFACE."""
130 if ord(SUD[wIndexL]==0):
131 self.wreg(rEP0FIFO,0);
132 self.wregAS(rEP0BC,1);
142 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
144 0x50, 0x51, #SDCZ2 Cruzer Mini Flash Drive (thin)
146 0x01, 0x02, 0x03, #Strings
151 #Configuration Descriptor
157 0x00, 0x01, 0x01, 0x00, 0xE0, 0x00, 0x09, 0x04, 0x00, 0x00,
159 0x08, #Mass Storage Bulk Only
164 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
166 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
170 # STRING descriptor 0--Language string
174 # 0x03, # bDescriptorType = string
175 # 0x09,0x04 # wLANGID(L/H) = English-United Sates
177 # STRING descriptor 1--Manufacturer ID
178 "\x10\x03G\x00o\x00o\x00d\x00F\x00E\x00T\x00",
179 # STRING descriptor 2 - Product ID
180 "\x1C\x03M\x00A\x00S\x00S\x00 \x00E\x00m\x00u\x00l\x00a\x00t\x00o\x00r\x00",
181 # STRING descriptor 3 - Serial Number ID
182 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
185 def get_status(self,SUD):
186 """Get the USB Setup Status."""
187 testbyte=ord(SUD[bmRequestType])
191 self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
192 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
193 self.wregAS(rEP0BC,2); #Load byte count, arm transfer, and ack CTL.
196 self.wreg(rEP0FIFO,0x00);
197 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
198 self.wregAS(rEP0BC,2);
201 if(ord(SUD[wIndexL])==0x83):
202 print "This code almost certainly doesn't work.";
203 self.wreg(rEP0FIFO,0x01); #Stall EP3
204 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
205 self.wregAS(rEP0BC,2);
207 print "Stalling unknown status.";
210 print "Stalling unknown status.";
214 """Handle IN3 input event."""
215 # Do nothing here, as it'll be taken care of elsewhere. The
216 # interrupt just means that the buffer is empty, not that we
217 # are expected to fill it.
220 """Handle an OUT1 output event."""
221 print "Got an output event, printing the result.";
222 l=self.rreg(rEP1OUTBC);
223 frame=self.readbytes(rEP1OUTFIFO,l);
224 self.handleCBW(frame);
227 def handleCBW(self,cbw):
228 """Handles an incoming Command Block Wrapper. See USB Mass
229 Storage Class for details."""
232 print "Invalid CBW length of %i bytes. Aborting." % len(cbw);
236 print "Invalid CBW signature: %s. Should be USBC; aborting." % sig;
240 dtlen=ord(cbw[8])+(ord(cbw[9])<<8)+(ord(cbw[10])<<16)+(ord(cbw[11])<<24);
242 dtdir=flags&0x80; # 0x80 for dev->host, 0x00 for host->dev
243 lun=ord(cbw[13])&0x0F; # Should be zero, as we only reported one LUN.
244 cblen=ord(cbw[14])&0x1F;
246 self.handleCB(cb,cblen,dtlen,dtdir);
248 def handleCB(self,cb,cblen,dtlen,dtdir):
249 """Handles a command block, then replies with a CSW."""
250 print "\nGot command block 0x%02x, requesting 0x%02x bytes" % (
253 status=00; #good, set to 1 for bad.
254 if verb==0x00: # Test Unit Ready
255 # Send nothing, just the success code.
257 elif verb==0x03: # Request Sense
258 print "Responding to Request Sense. Needed for Macs.";
259 response=[0x70, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0A,
260 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
264 self.writebytes(rEP3INFIFO,
266 self.wreg(rEP3INBC,len(response));
267 elif verb==0x12: #Inquiry
268 #print "Responding to CB inquiry.";
270 0x00, # 00 for Direct, 1F for "no floppy"
271 0x80, # make 0x80 for removable media
273 0x01, # Response Data Format
274 0x1f, #Additional length.
277 ord('G'),ord('o'),ord('o'),ord('d'),ord('F'),ord('E'),ord('T'),0x20,
279 ord('G'),ord('o'),ord('o'),ord('d'),ord('F'),ord('E'),ord('T'),0x20,
280 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
281 ord('0'),ord('.'),ord('0'),ord('1')]
282 #print "Sending %i byte reply to %i byte query." % (
283 # len(response),dtlen);
284 #while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
285 # #Wait for the packet to complete before sending the next.
286 # print "Waiting to complete inquiry."
288 self.writebytes(rEP3INFIFO,
290 self.wregAS(rEP3INBC,
293 #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
294 #while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
295 # #Wait for the packet to complete before sending the next.
296 # print "Waiting to complete inquiry."
298 elif verb==0x1e: #Prevent/Allow Removal
299 # Give a good status to pretend we understand.
301 elif verb==0x1A: #Mode Sense (6)
302 # I should probably send six bytes here.
303 response=[0x12,0,0,0, 0,0,0,0x1C];
304 self.writebytes(rEP3INFIFO,
306 self.wregAS(rEP3INBC,
308 elif verb==0x23: #Read Format Capacity
310 0x00, 0,0x00,0x08, #Capacity list length.
311 0,0x00,x10,0x00, # Number of sectors, implying 10MB.
312 0x01,0x00, #reserved/desciptor code.
313 0x02,0x00 # 512 bytes/sector. Why is this twice?
315 self.writebytes(rEP3INFIFO,
317 self.wregAS(rEP3INBC,
319 elif verb==0x25: #Read Capacity
321 0x00, 0,0x0f,0xFF, # Last LBA; might have endianness backward.
322 0x00,0x00,0x02,0x00 # Block length of 512 bytes.
324 self.writebytes(rEP3INFIFO,
326 self.wregAS(rEP3INBC,
328 elif verb==0x28: #READ SECTOR
337 print "Fetching %i blocks starting at LBA %i." % (count,baselba);
338 for i in range(0,count):
339 data=self.getSectorData(baselba+count);
341 print "Sending block fragment %i,%i" % (i,j);
342 #Transmit each 64-byte block fragment, then wait for next.
343 while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ): pass;
344 response=data[j*64:j*64+64];
345 self.writebytes(rEP3INFIFO,
347 self.wregAS(rEP3INBC,
350 elif verb==0x2A: #WRITE SECTOR
351 print "Haven't implemented WRITE SECTOR.";
354 print "ERROR: Unknown SCSI command block verb %02x." % verb;
355 status=1; #Command Failed
357 print "Perhaps I should send %i bytes of dummy data here." % dtlen;
361 #Now we need to send the CSW.
364 ord('U'),ord('S'),ord('B'),ord('S'),
365 #CBW key; must be the same as the one we're replying to.
366 ord(cbw[4]),ord(cbw[5]),ord(cbw[6]),ord(cbw[7]),
367 #CSW Data Residue, probably oughtn't be zeroed.
369 #Status byte: 00 for good, 01 for bad.
371 self.writebytes(rEP3INFIFO,
373 self.wregAS(rEP3INBC,len(csw));
377 #Initialize FET and set baud rate
378 client=GoodFETMAXUSBMass();
381 client.MAXUSBsetup();