mirror of
https://github.com/dwhinham/mt32-pi.git
synced 2026-10-27 06:21:59 +00:00
Add temporary Circle patches to fix USB MS on Pi 3
Temporary for for rsta2/circle#211 until a new version is made available.
This commit is contained in:
1 parent
b390fd59e3
commit
669284f3d7
3 files changed
+309
No files matched your search
@@ -18,6 +18,8 @@ $(CIRCLE_STDLIB_CONFIG) $(CIRCLE_CONFIG)&:
|
||||
# Apply patches
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-minimal-usb-drivers.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-pi4-usb-fix.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-fix-hard-errors.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-retry-bulk-transfer.patch
|
||||
|
||||
ifeq ($(strip $(GC_SECTIONS)),1)
|
||||
# Enable function/data sections for circle-stdlib
|
||||
@@ -117,6 +119,8 @@ clean:
|
||||
#
|
||||
veryclean: clean
|
||||
# Reverse patches
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-retry-bulk-transfer.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-fix-hard-errors.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-pi4-usb-fix.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-minimal-usb-drivers.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(FLUIDSYNTHHOME) < patches/fluidsynth-2.1.7-circle.patch
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
From 17e015181d02e4b676204e201a9fb4b8e34f730b Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Mon, 15 Mar 2021 18:20:06 +0100
|
||||
Subject: [PATCH] usb/usbmassdevice: Fix hard errors in reset recovery
|
||||
|
||||
The recovery function did not work at all, because it was never used
|
||||
before. Now on the RPi 3A+, Zero and probably A+ it is necessary and
|
||||
has been corrected. Unfortunately this does not solve all problems
|
||||
with USB flash drive access on these RPi models. Reads or writes may
|
||||
still fail, but not as often.
|
||||
|
||||
Issue #211
|
||||
---
|
||||
include/circle/usb/usb.h | 6 ++++-
|
||||
lib/usb/usbmassdevice.cpp | 50 ++++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 46 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/include/circle/usb/usb.h b/include/circle/usb/usb.h
|
||||
index 06dfdc9d..4fb61a98 100644
|
||||
--- a/include/circle/usb/usb.h
|
||||
+++ b/include/circle/usb/usb.h
|
||||
@@ -2,7 +2,7 @@
|
||||
// usb.h
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -84,6 +84,7 @@ PACKED;
|
||||
|
||||
#define REQUEST_TO_DEVICE 0
|
||||
#define REQUEST_TO_INTERFACE 1
|
||||
+#define REQUEST_TO_ENDPOINT 2
|
||||
#define REQUEST_TO_OTHER 3
|
||||
|
||||
// Standard Request Codes
|
||||
@@ -95,6 +96,9 @@ PACKED;
|
||||
#define SET_CONFIGURATION 9
|
||||
#define SET_INTERFACE 11
|
||||
|
||||
+// Standard Feature Selectors
|
||||
+#define ENDPOINT_HALT 0
|
||||
+
|
||||
// Descriptor Types
|
||||
#define DESCRIPTOR_DEVICE 1
|
||||
#define DESCRIPTOR_CONFIGURATION 2
|
||||
diff --git a/lib/usb/usbmassdevice.cpp b/lib/usb/usbmassdevice.cpp
|
||||
index da631e18..10de3f14 100644
|
||||
--- a/lib/usb/usbmassdevice.cpp
|
||||
+++ b/lib/usb/usbmassdevice.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// usbmassdevice.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -28,8 +28,14 @@
|
||||
#include <circle/new.h>
|
||||
#include <assert.h>
|
||||
|
||||
+#define MAX_TRIES 8 // max. read / write attempts
|
||||
+
|
||||
// USB Mass Storage Bulk-Only Transport
|
||||
|
||||
+// Class-specific requests
|
||||
+#define GET_MAX_LUN 0xFE
|
||||
+#define BULK_ONLY_MASS_STORAGE_RESET 0xFF
|
||||
+
|
||||
// Command Block Wrapper
|
||||
struct TCBW
|
||||
{
|
||||
@@ -418,7 +424,7 @@ boolean CUSBBulkOnlyMassStorageDevice::Configure (void)
|
||||
|
||||
int CUSBBulkOnlyMassStorageDevice::Read (void *pBuffer, size_t nCount)
|
||||
{
|
||||
- unsigned nTries = 4;
|
||||
+ unsigned nTries = MAX_TRIES;
|
||||
|
||||
int nResult;
|
||||
|
||||
@@ -443,7 +449,7 @@ int CUSBBulkOnlyMassStorageDevice::Read (void *pBuffer, size_t nCount)
|
||||
|
||||
int CUSBBulkOnlyMassStorageDevice::Write (const void *pBuffer, size_t nCount)
|
||||
{
|
||||
- unsigned nTries = 4;
|
||||
+ unsigned nTries = MAX_TRIES;
|
||||
|
||||
int nResult;
|
||||
|
||||
@@ -629,7 +635,25 @@ int CUSBBulkOnlyMassStorageDevice::Command (void *pCmdBlk, size_t nCmdBlkLen,
|
||||
{
|
||||
CLogger::Get ()->Write (FromUmsd, LogError, "CSW transfer failed");
|
||||
|
||||
- return -1;
|
||||
+ if (pHost->ControlMessage (GetEndpoint0 (),
|
||||
+ REQUEST_TO_ENDPOINT | REQUEST_OUT, CLEAR_FEATURE,
|
||||
+ ENDPOINT_HALT, m_pEndpointIn->GetNumber () | 0x80,
|
||||
+ 0, 0) < 0)
|
||||
+ {
|
||||
+ CLogger::Get ()->Write (FromUmsd, LogDebug,
|
||||
+ "Cannot clear halt on endpoint IN");
|
||||
+
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ m_pEndpointIn->ResetPID ();
|
||||
+
|
||||
+ if (pHost->Transfer (m_pEndpointIn, pCSW, sizeof *pCSW) != (int) sizeof *pCSW)
|
||||
+ {
|
||||
+ CLogger::Get ()->Write (FromUmsd, LogError, "CSW transfer failed twice");
|
||||
+
|
||||
+ return -1;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (pCSW->dCSWSignature != CSWSIGNATURE)
|
||||
@@ -666,23 +690,31 @@ int CUSBBulkOnlyMassStorageDevice::Reset (void)
|
||||
CUSBHostController *pHost = GetHost ();
|
||||
assert (pHost != 0);
|
||||
|
||||
- if (pHost->ControlMessage (GetEndpoint0 (), 0x21, 0xFF, 0, 0x00, 0, 0) < 0)
|
||||
+ if (pHost->ControlMessage (GetEndpoint0 (),
|
||||
+ REQUEST_CLASS | REQUEST_TO_INTERFACE | REQUEST_OUT,
|
||||
+ BULK_ONLY_MASS_STORAGE_RESET, 0, GetInterfaceNumber (), 0, 0) < 0)
|
||||
{
|
||||
CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot reset device");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (pHost->ControlMessage (GetEndpoint0 (), 0x02, 1, 0, 1, 0, 0) < 0)
|
||||
+ CTimer::Get ()->MsDelay (100);
|
||||
+
|
||||
+ if (pHost->ControlMessage (GetEndpoint0 (),
|
||||
+ REQUEST_TO_ENDPOINT | REQUEST_OUT, CLEAR_FEATURE,
|
||||
+ ENDPOINT_HALT, m_pEndpointIn->GetNumber () | 0x80, 0, 0) < 0)
|
||||
{
|
||||
- CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot clear halt on endpoint 1");
|
||||
+ CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot clear halt on endpoint IN");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (pHost->ControlMessage (GetEndpoint0 (), 0x02, 1, 0, 2, 0, 0) < 0)
|
||||
+ if (pHost->ControlMessage (GetEndpoint0 (),
|
||||
+ REQUEST_TO_ENDPOINT | REQUEST_OUT, CLEAR_FEATURE,
|
||||
+ ENDPOINT_HALT, m_pEndpointOut->GetNumber (), 0, 0) < 0)
|
||||
{
|
||||
- CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot clear halt on endpoint 2");
|
||||
+ CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot clear halt on endpoint OUT");
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
From 88240494fa02a09cbebd94a3ce35d87303cd0a0e Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Thu, 18 Mar 2021 13:12:06 +0100
|
||||
Subject: [PATCH] usb/dwhcidevice: Retry bulk transfers on xact error
|
||||
|
||||
The access to some (especially USB 3.0) flash drives on RPi 3A+ and
|
||||
Zero was not reliable before, because xact errors occurred from time
|
||||
to time. Now transfers will be automatically retried several times,
|
||||
if such an error occurs on a bulk endpoint.
|
||||
|
||||
Issue #211
|
||||
---
|
||||
include/circle/usb/dwhcixferstagedata.h | 4 +++-
|
||||
lib/usb/dwhcidevice.cpp | 17 ++++++++++++++++-
|
||||
lib/usb/dwhcixferstagedata.cpp | 25 +++++++++++++++++++++++--
|
||||
3 files changed, 42 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/include/circle/usb/dwhcixferstagedata.h b/include/circle/usb/dwhcixferstagedata.h
|
||||
index 5300c74c..8890cdfb 100644
|
||||
--- a/include/circle/usb/dwhcixferstagedata.h
|
||||
+++ b/include/circle/usb/dwhcixferstagedata.h
|
||||
@@ -2,7 +2,7 @@
|
||||
// dwhcixferstagedata.h
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -80,6 +80,7 @@ class CDWHCITransferStageData
|
||||
boolean IsStageComplete (void) const;
|
||||
u32 GetResultLen (void) const;
|
||||
boolean IsTimeout (void) const;
|
||||
+ boolean IsRetryOK (void) const;
|
||||
|
||||
CUSBRequest *GetURB (void) const;
|
||||
CUSBDevice *GetDevice (void) const;
|
||||
@@ -109,6 +110,7 @@ class CDWHCITransferStageData
|
||||
unsigned m_nState;
|
||||
unsigned m_nSubState;
|
||||
u32 m_nTransactionStatus;
|
||||
+ unsigned m_nErrorCount;
|
||||
|
||||
u32 *m_pTempBuffer;
|
||||
void *m_pBufferPointer;
|
||||
diff --git a/lib/usb/dwhcidevice.cpp b/lib/usb/dwhcidevice.cpp
|
||||
index c59c5fab..79b22268 100644
|
||||
--- a/lib/usb/dwhcidevice.cpp
|
||||
+++ b/lib/usb/dwhcidevice.cpp
|
||||
@@ -1064,7 +1064,22 @@ void CDWHCIDevice::ChannelInterruptHandler (unsigned nChannel)
|
||||
{
|
||||
case StageStateNoSplitTransfer:
|
||||
nStatus = pStageData->GetTransactionStatus ();
|
||||
- if (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK)
|
||||
+ if ( (nStatus & DWHCI_HOST_CHAN_INT_XACT_ERROR)
|
||||
+ && pURB->GetEndpoint ()->GetType () == EndpointTypeBulk
|
||||
+ && pStageData->IsRetryOK ())
|
||||
+ {
|
||||
+#ifndef USE_USB_SOF_INTR
|
||||
+ StartTransaction (pStageData);
|
||||
+#else
|
||||
+ m_pStageData[nChannel] = 0;
|
||||
+ FreeChannel (nChannel);
|
||||
+
|
||||
+ QueueTransaction (pStageData);
|
||||
+#endif
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK)
|
||||
{
|
||||
CLogger::Get ()->Write (FromDWHCI, LogError,
|
||||
"Transaction failed (status 0x%X)", nStatus);
|
||||
diff --git a/lib/usb/dwhcixferstagedata.cpp b/lib/usb/dwhcixferstagedata.cpp
|
||||
index 63cf64eb..32f3f356 100644
|
||||
--- a/lib/usb/dwhcixferstagedata.cpp
|
||||
+++ b/lib/usb/dwhcixferstagedata.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// dwhcixferstagedata.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <circle/timer.h>
|
||||
#include <assert.h>
|
||||
|
||||
+#define MAX_BULK_TRIES 8
|
||||
+
|
||||
CDWHCITransferStageData::CDWHCITransferStageData (unsigned nChannel,
|
||||
CUSBRequest *pURB,
|
||||
boolean bIn,
|
||||
@@ -42,6 +44,7 @@ CDWHCITransferStageData::CDWHCITransferStageData (unsigned nChannel,
|
||||
m_nState (0),
|
||||
m_nSubState (0),
|
||||
m_nTransactionStatus (0),
|
||||
+ m_nErrorCount (0),
|
||||
m_pTempBuffer (0),
|
||||
m_nStartTicksHZ (0),
|
||||
m_pFrameScheduler (0)
|
||||
@@ -186,9 +189,17 @@ void CDWHCITransferStageData::TransactionComplete (u32 nStatus, u32 nPacketsLeft
|
||||
assert (m_bIn);
|
||||
|
||||
m_nPackets = 0; // no data is available, complete transfer
|
||||
+
|
||||
+ return;
|
||||
}
|
||||
|
||||
- return;
|
||||
+ // bulk transfers with xact error will be retried, return otherwise
|
||||
+ if ( !(nStatus & DWHCI_HOST_CHAN_INT_XACT_ERROR)
|
||||
+ || m_pEndpoint->GetType () != EndpointTypeBulk
|
||||
+ || ++m_nErrorCount > MAX_BULK_TRIES)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
u32 nPacketsTransfered = m_nPacketsPerTransaction - nPacketsLeft;
|
||||
@@ -214,6 +225,11 @@ void CDWHCITransferStageData::TransactionComplete (u32 nStatus, u32 nPacketsLeft
|
||||
assert (nPacketsTransfered <= m_nPackets);
|
||||
m_nPackets -= nPacketsTransfered;
|
||||
|
||||
+ if (!m_bSplitTransaction)
|
||||
+ {
|
||||
+ m_nPacketsPerTransaction = m_nPackets;
|
||||
+ }
|
||||
+
|
||||
// if (m_nTotalBytesTransfered > m_nTransferSize) this will be false:
|
||||
if (m_nTransferSize - m_nTotalBytesTransfered < m_nBytesPerTransaction)
|
||||
{
|
||||
@@ -490,6 +506,11 @@ boolean CDWHCITransferStageData::IsTimeout (void) const
|
||||
return CTimer::Get ()->GetTicks ()-m_nStartTicksHZ >= m_nTimeoutHZ ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
+boolean CDWHCITransferStageData::IsRetryOK (void) const
|
||||
+{
|
||||
+ return m_nErrorCount <= MAX_BULK_TRIES;
|
||||
+}
|
||||
+
|
||||
CUSBRequest *CDWHCITransferStageData::GetURB (void) const
|
||||
{
|
||||
assert (m_pURB != 0);
|
||||
Reference in new issue
Block a user