@@ -85,6 +85,10 @@ def from_binary(self, binary):
85
85
) = ustruct .unpack ("<LLLBBB16s" , binary )
86
86
87
87
88
+ class BadCbw (RuntimeError ):
89
+ pass
90
+
91
+
88
92
class CSW :
89
93
"""Command Status Wrapper - handles status messages from the device to the host"""
90
94
@@ -194,7 +198,8 @@ def try_to_prepare_cbw(self, args=None):
194
198
"""
195
199
try :
196
200
self .prepare_cbw ()
197
- except KeyError :
201
+ except (KeyError , RuntimeError ):
202
+ # RuntimeError is raised when the device isn't open yet, so let's just retry
198
203
self .timer .init (mode = Timer .ONE_SHOT , period = 2000 , callback = self .try_to_prepare_cbw )
199
204
200
205
def handle_interface_control_xfer (self , stage , request ):
@@ -221,13 +226,13 @@ def handle_interface_control_xfer(self, stage, request):
221
226
return False
222
227
223
228
def reset (self ):
224
- """Theoretically reset, in reality just break things a bit at the moment """
229
+ """Perform a Reset Revovery """
225
230
self .log ("reset()" )
226
- # This doesn't work properly at the moment, needs additional
227
- # functionality in the C side
228
231
self .stage = type (self ).MSC_STAGE_CMD
229
232
self .transferred_length = 0
230
233
self .storage_device .reset ()
234
+ self .set_ep_stall (self .ep_in , False )
235
+ self .set_ep_stall (self .ep_out , False )
231
236
self .prepare_cbw ()
232
237
return True
233
238
@@ -296,7 +301,14 @@ def handle_cbw(self):
296
301
self .csw .dCSWDataResidue = 0
297
302
self .csw .bCSWStatus = CSW .STATUS_PASSED
298
303
299
- status = int (self .validate_cbw ())
304
+ try :
305
+ status = int (self .validate_cbw ())
306
+ except BadCbw as exc :
307
+ self .log (str (exc ))
308
+ self .set_ep_stall (self .ep_in , True )
309
+ self .set_ep_stall (self .ep_out , True )
310
+ return False
311
+
300
312
if status != CSW .STATUS_PASSED :
301
313
self .log (f"Didn't pass: { status } " )
302
314
self .prepare_for_csw (status = status )
@@ -388,22 +400,17 @@ def validate_cbw(self) -> bool:
388
400
return CSW .STATUS_PHASE_ERROR
389
401
390
402
if len (self .rx_data ) != 31 :
391
- self .log ("Wrong length" )
392
- return CSW .STATUS_FAILED
403
+ raise BadCbw ("Invalid: Wrong CBW length" )
393
404
394
405
if self .cbw .dCBWSignature != type (self ).CBW_SIGNATURE :
395
- self .log ("Wrong sig" )
396
- self .log (str (self .cbw .dCBWSignature ))
397
- return CSW .STATUS_FAILED
406
+ raise BadCbw (f"Invalid: Wrong sig: { str (self .cbw .dCBWSignature )} " )
398
407
399
408
# Meaningful checks (6.2.2)
400
409
if self .cbw .bCBWLUN > 15 or not 0 < self .cbw .bCBWCBLength < 17 :
401
- self .log ("Wrong length" )
402
- return CSW .STATUS_FAILED
410
+ raise BadCbw ("Not meaningful: Wrong length command or invalid LUN" )
403
411
404
412
if self .cbw .bCBWLUN != self .lun :
405
- self .log ("Wrong LUN" )
406
- return CSW .STATUS_FAILED
413
+ raise BadCbw ("Not meaningful: Wrong LUN" )
407
414
408
415
# Check if this is a valid SCSI command
409
416
try :
0 commit comments