11package msc
22
33import (
4+ "errors"
45 "machine"
56 "machine/usb"
67 "machine/usb/descriptor"
78 "machine/usb/msc/csw"
89 "machine/usb/msc/scsi"
10+ "math/bits"
911 "time"
1012)
1113
@@ -23,6 +25,8 @@ const (
2325 mscInterface = 2
2426)
2527
28+ var errInvalidBlockSize = errors .New ("usb/msc: invalid block size" )
29+
2630var MSC * msc
2731
2832type msc struct {
@@ -60,20 +64,41 @@ type msc struct {
6064}
6165
6266// Port returns the USB Mass Storage port
63- func Port (dev machine.BlockDevice ) * msc {
67+ func Port (dev machine.BlockDevice ) ( * msc , error ) {
6468 if MSC == nil {
65- MSC = newMSC (dev )
69+ msc , err := newMSC (dev )
70+ if err != nil {
71+ return nil , err
72+ }
73+ MSC = msc
6674 }
67- return MSC
75+ return MSC , nil
6876}
6977
70- func newMSC (dev machine.BlockDevice ) * msc {
78+ func newMSC (dev machine.BlockDevice ) ( * msc , error ) {
7179 // Size our buffer to match the maximum packet size of the IN endpoint
7280 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+
7398 m := & msc {
7499 // Some platforms require reads/writes to be aligned to the full underlying hardware block
75100 blockCache : make ([]byte , dev .WriteBlockSize ()),
76- blockSizeUSB : 512 ,
101+ blockSizeUSB : blockSizeUSB ,
77102 buf : make ([]byte , dev .WriteBlockSize ()),
78103 cswBuf : make ([]byte , csw .MsgLen ),
79104 cbw : & CBW {Data : make ([]byte , 31 )},
@@ -114,7 +139,7 @@ func newMSC(dev machine.BlockDevice) *msc {
114139
115140 go m .processTasks ()
116141
117- return m
142+ return m , nil
118143}
119144
120145func (m * msc ) processTasks () {
0 commit comments