@@ -21,30 +21,30 @@ class SDWire(StorageMuxFlasherInterface, Driver):
2121
2222 storage_device : str | None = field (default = None )
2323
24+ def effective_storage_device (self ):
25+ if self .storage_device is None :
26+ context = pyudev .Context ()
27+ for udevice in (
28+ context .list_devices (subsystem = "usb" )
29+ .match_attribute ("busnum" , self .dev .bus )
30+ .match_attribute ("devnum" , self .dev .address )
31+ ):
32+ # find siblings block device
33+ for block in filter (lambda d : d .subsystem == "block" , udevice .parent .children ):
34+ # find stable device link under by-diskseq
35+ for storage_device in filter (
36+ lambda link : link .startswith ("/dev/disk/by-diskseq/" ), block .device_links
37+ ):
38+ return storage_device
39+ return None
40+ else :
41+ return self .storage_device
42+
2443 def __post_init__ (self ):
2544 if hasattr (super (), "__post_init__" ):
2645 super ().__post_init__ ()
2746
2847 for dev in usb .core .find (idVendor = 0x04E8 , idProduct = 0x6001 , find_all = True ):
29- if self .storage_device is None :
30- context = pyudev .Context ()
31- # find matching udev device
32- for udevice in (
33- context .list_devices (subsystem = "usb" )
34- .match_attribute ("busnum" , dev .bus )
35- .match_attribute ("devnum" , dev .address )
36- ):
37- # find siblings block device
38- for block in filter (lambda d : d .subsystem == "block" , udevice .parent .children ):
39- # find stable device link under by-diskseq
40- for storage_device in filter (
41- lambda link : link .startswith ("/dev/disk/by-diskseq/" ), block .device_links
42- ):
43- self .storage_device = storage_device
44-
45- if self .storage_device is None :
46- raise FileNotFoundError ("failed to find sdcard driver on sd-wire device" )
47-
4848 product = usb .util .get_string (dev , dev .iProduct )
4949 serial = usb .util .get_string (dev , dev .iSerialNumber )
5050
@@ -60,6 +60,9 @@ def __post_init__(self):
6060 bInterfaceProtocol = 0xFF ,
6161 )
6262
63+ if self .effective_storage_device () is None :
64+ raise FileNotFoundError ("failed to find sdcard driver on sd-wire device" )
65+
6366 return
6467
6568 raise FileNotFoundError ("failed to find sd-wire device" )
@@ -100,30 +103,43 @@ def off(self):
100103
101104 async def wait_for_storage_device (self ):
102105 with fail_after (10 ):
106+ storage_device = self .effective_storage_device ()
107+
103108 while True :
104109 # https://stackoverflow.com/a/2774125
105- fd = os .open (self .storage_device , os .O_WRONLY )
106110 try :
111+ fd = os .open (storage_device , os .O_WRONLY )
107112 if os .lseek (fd , 0 , os .SEEK_END ) > 0 :
108113 break
114+ except OSError as e :
115+ match e .errno :
116+ case 123 : # No medium found
117+ pass
118+ case 5 : # Input/output error
119+ pass
120+ case _:
121+ raise
109122 finally :
110- os .close (fd )
123+ if "fd" in locals ():
124+ os .close (fd )
111125 await sleep (1 )
112126
127+ return storage_device
128+
113129 @export
114130 async def write (self , src : str ):
115131 self .host ()
116- await self .wait_for_storage_device ()
117- async with await FileWriteStream .from_path (self . storage_device ) as stream :
132+ storage_device = await self .wait_for_storage_device ()
133+ async with await FileWriteStream .from_path (storage_device ) as stream :
118134 async with self .resource (src ) as res :
119135 async for chunk in res :
120136 await stream .send (chunk )
121137
122138 @export
123139 async def read (self , dst : str ):
124140 self .host ()
125- await self .wait_for_storage_device ()
126- async with await FileReadStream .from_path (self . storage_device ) as stream :
141+ storage_device = await self .wait_for_storage_device ()
142+ async with await FileReadStream .from_path (storage_device ) as stream :
127143 async with self .resource (dst ) as res :
128144 async for chunk in stream :
129145 await res .send (chunk )
0 commit comments