Skip to content

Commit 6ac20fc

Browse files
committed
usb/msc: wait for interrupt instead of polling a flag
This should make usb/msc a whole lot more efficient by pausing the worker goroutine and waiting for an interrupt to unpause it instead of waiting in a loop and sleeping for 0.1ms each cycle. In other words, this should make it both faster (no unnecessary delay due to the time.Sleep) and more efficient (no polling).
1 parent 869366b commit 6ac20fc

File tree

2 files changed

+27
-27
lines changed

2 files changed

+27
-27
lines changed

src/machine/usb/msc/msc.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package msc
22

33
import (
4+
"internal/task"
45
"machine"
56
"machine/usb"
67
"machine/usb/descriptor"
78
"machine/usb/msc/csw"
89
"machine/usb/msc/scsi"
9-
"time"
1010
)
1111

1212
type mscState uint8
@@ -26,14 +26,14 @@ const (
2626
var MSC *msc
2727

2828
type msc struct {
29-
buf []byte // Buffer for incoming/outgoing data
30-
blockCache []byte // Buffer for block read/write data
31-
taskQueued bool // Flag to indicate if the buffer has a task queued
32-
rxStalled bool // Flag to indicate if the RX endpoint is stalled
33-
txStalled bool // Flag to indicate if the TX endpoint is stalled
34-
maxPacketSize uint32 // Maximum packet size for the IN endpoint
35-
respStatus csw.Status // Response status for the last command
36-
sendZLP bool // Flag to indicate if a zero-length packet should be sent before sending CSW
29+
buf []byte // Buffer for incoming/outgoing data
30+
blockCache []byte // Buffer for block read/write data
31+
taskWaiter task.Waiter // Waiter for events outside interrupt context
32+
rxStalled bool // Flag to indicate if the RX endpoint is stalled
33+
txStalled bool // Flag to indicate if the TX endpoint is stalled
34+
maxPacketSize uint32 // Maximum packet size for the IN endpoint
35+
respStatus csw.Status // Response status for the last command
36+
sendZLP bool // Flag to indicate if a zero-length packet should be sent before sending CSW
3737

3838
cbw *CBW // Last received Command Block Wrapper
3939
queuedBytes uint32 // Number of bytes queued for sending
@@ -120,21 +120,21 @@ func newMSC(dev machine.BlockDevice) *msc {
120120
func (m *msc) processTasks() {
121121
// Process tasks that cannot be done in an interrupt context
122122
for {
123-
if m.taskQueued {
124-
cmd := m.cbw.SCSICmd()
125-
switch cmd.CmdType() {
126-
case scsi.CmdWrite:
127-
m.scsiWrite(cmd, m.buf)
128-
case scsi.CmdUnmap:
129-
m.scsiUnmap(m.buf)
130-
}
131-
132-
// Acknowledge the received data from the host
133-
m.queuedBytes = 0
134-
m.taskQueued = false
135-
machine.AckUsbOutTransfer(usb.MSC_ENDPOINT_OUT)
123+
// Wait for the next task to arrive.
124+
m.taskWaiter.Wait()
125+
126+
cmd := m.cbw.SCSICmd()
127+
switch cmd.CmdType() {
128+
case scsi.CmdWrite:
129+
m.scsiWrite(cmd, m.buf)
130+
case scsi.CmdUnmap:
131+
m.scsiUnmap(m.buf)
136132
}
137-
time.Sleep(100 * time.Microsecond)
133+
134+
// Acknowledge the received data from the host
135+
m.queuedBytes = 0
136+
m.taskWaiter.Done()
137+
machine.AckUsbOutTransfer(usb.MSC_ENDPOINT_OUT)
138138
}
139139
}
140140

src/machine/usb/msc/scsi.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ func (m *msc) scsiQueueTask(cmdType scsi.CmdType, b []byte) bool {
250250
}
251251

252252
// Save the incoming data in our buffer for processing outside of interrupt context.
253-
if m.taskQueued {
253+
if m.taskWaiter.Working() {
254254
// If we already have a full task queue we can't accept this data
255255
m.sendScsiError(csw.StatusFailed, scsi.SenseAbortedCommand, scsi.SenseCodeMsgReject)
256256
return true
@@ -267,14 +267,14 @@ func (m *msc) scsiQueueTask(cmdType scsi.CmdType, b []byte) bool {
267267
case scsi.CmdWrite:
268268
// If we're writing data wait until we have a full write block of data that can be processed.
269269
if m.queuedBytes == uint32(cap(m.blockCache)) {
270-
m.taskQueued = true
270+
m.taskWaiter.Resume()
271271
}
272272
case scsi.CmdUnmap:
273-
m.taskQueued = true
273+
m.taskWaiter.Resume()
274274
}
275275

276276
// Don't acknowledge the incoming data until we can process it.
277-
return !m.taskQueued
277+
return !m.taskWaiter.Working()
278278
}
279279

280280
func (m *msc) sendScsiError(status csw.Status, key scsi.Sense, code scsi.SenseCode) {

0 commit comments

Comments
 (0)