1
1
package msc
2
2
3
3
import (
4
+ "errors"
4
5
"machine"
5
6
"machine/usb"
6
7
"machine/usb/descriptor"
7
8
"machine/usb/msc/csw"
8
9
"machine/usb/msc/scsi"
10
+ "math/bits"
9
11
"time"
10
12
)
11
13
@@ -23,6 +25,8 @@ const (
23
25
mscInterface = 2
24
26
)
25
27
28
+ var errInvalidBlockSize = errors .New ("usb/msc: invalid block size" )
29
+
26
30
var MSC * msc
27
31
28
32
type msc struct {
@@ -60,20 +64,41 @@ type msc struct {
60
64
}
61
65
62
66
// Port returns the USB Mass Storage port
63
- func Port (dev machine.BlockDevice ) * msc {
67
+ func Port (dev machine.BlockDevice ) ( * msc , error ) {
64
68
if MSC == nil {
65
- MSC = newMSC (dev )
69
+ msc , err := newMSC (dev )
70
+ if err != nil {
71
+ return nil , err
72
+ }
73
+ MSC = msc
66
74
}
67
- return MSC
75
+ return MSC , nil
68
76
}
69
77
70
- func newMSC (dev machine.BlockDevice ) * msc {
78
+ func newMSC (dev machine.BlockDevice ) ( * msc , error ) {
71
79
// Size our buffer to match the maximum packet size of the IN endpoint
72
80
maxPacketSize := descriptor .EndpointMSCIN .GetMaxPacketSize ()
81
+
82
+ // Windows only supports block sizes of 512 or 4096 bytes, other systems are
83
+ // probably similar.
84
+ blockSize := max (dev .EraseBlockSize (), dev .WriteBlockSize ())
85
+ if bits .OnesCount32 (uint32 (blockSize )) != 1 {
86
+ return nil , errInvalidBlockSize // not a power of two
87
+ }
88
+ var blockSizeUSB uint32
89
+ switch {
90
+ case blockSize <= 512 :
91
+ blockSizeUSB = 512
92
+ case blockSize <= 4096 :
93
+ blockSizeUSB = 4096
94
+ default :
95
+ return nil , errInvalidBlockSize
96
+ }
97
+
73
98
m := & msc {
74
99
// Some platforms require reads/writes to be aligned to the full underlying hardware block
75
100
blockCache : make ([]byte , dev .WriteBlockSize ()),
76
- blockSizeUSB : 512 ,
101
+ blockSizeUSB : blockSizeUSB ,
77
102
buf : make ([]byte , dev .WriteBlockSize ()),
78
103
cswBuf : make ([]byte , csw .MsgLen ),
79
104
cbw : & CBW {Data : make ([]byte , 31 )},
@@ -114,7 +139,7 @@ func newMSC(dev machine.BlockDevice) *msc {
114
139
115
140
go m .processTasks ()
116
141
117
- return m
142
+ return m , nil
118
143
}
119
144
120
145
func (m * msc ) processTasks () {
0 commit comments