20 #include "UsbMassStorageDevice.h" 21 #include "modules/system/usb/Usb.h" 22 #include "modules/system/usb/UsbDevice.h" 23 #include "pedigree/kernel/Log.h" 24 #include "pedigree/kernel/utilities/PointerGuard.h" 25 #include "pedigree/kernel/utilities/Vector.h" 27 UsbMassStorageDevice::UsbMassStorageDevice(
UsbDevice *dev)
33 UsbMassStorageDevice::~UsbMassStorageDevice()
39 for (
size_t i = 0; i <
m_pInterface->endpointList.count(); i++)
42 if (!
m_pInEndpoint && (pEndpoint->nTransferType == Endpoint::Bulk) &&
45 if (!m_pOutEndpoint && (pEndpoint->nTransferType == Endpoint::Bulk) &&
47 m_pOutEndpoint = pEndpoint;
54 ERROR(
"USB: MSD: No IN endpoint");
60 ERROR(
"USB: MSD: No OUT endpoint");
71 uint8_t *nMaxLUN =
new uint8_t(0);
73 UsbRequestDirection::In | MassStorageRequest, MassStorageGetMaxLUN,
75 reinterpret_cast<uintptr_t>(nMaxLUN)))
77 ERROR(
"USB: MSD: Couldn't get maximum LUN");
80 m_nUnits = *nMaxLUN + 1;
88 bool UsbMassStorageDevice::massStorageReset()
91 MassStorageRequest, MassStorageReset, 0,
m_pInterface->nInterface);
95 size_t nUnit, uintptr_t pCommand, uint8_t nCommandSize,
96 uintptr_t pRespBuffer, uint16_t nRespBytes,
bool bWrite)
100 ByteSet(pCbw, 0,
sizeof(
Cbw));
102 pCbw->nDataBytes = HOST_TO_LITTLE32(nRespBytes);
103 pCbw->nFlags = bWrite ? 0 : 0x80;
105 pCbw->nCommandSize = nCommandSize;
107 pCbw->pCommand, reinterpret_cast<void *>(pCommand), nCommandSize);
110 syncOut(m_pOutEndpoint, reinterpret_cast<uintptr_t>(pCbw), 31);
113 if (nResult == -Stall)
135 "USB: MSD: Performing " <<
Dec << nRespBytes <<
Hex <<
" byte " 136 << (bWrite ?
"write" :
"read"));
138 nResult = syncOut(m_pOutEndpoint, pRespBuffer, nRespBytes);
144 ((nResult < nRespBytes) && (!bWrite)))
147 bool bClearResult =
false;
155 DEBUG_LOG(
"USB: MSD: Endpoint stalled, but clearing failed. " 156 "Performing reset.");
169 syncIn(
m_pInEndpoint, reinterpret_cast<uintptr_t>(pCsw), 13);
172 if (nResult == -Stall)
180 DEBUG_LOG(
"USB: MSD: Couldn't recover cleanly from endpoint " 181 "stall, mass storage reset completed");
184 else if (nResult < 0)
187 "USB: MSD: Reading CSW after clearing stall ended up " 188 "failing with status " 194 DEBUG_LOG(
"USB: MSD: Recovered from endpoint stall");
195 return !pCsw->nStatus;
201 Csw *pCsw =
reinterpret_cast<Csw *
>(pRespBuffer);
202 if (pCsw->nSig == CswSig)
205 "USB: MSD: Early CSW with status " 206 << pCsw->nStatus <<
", residue: " << pCsw->nResidue);
207 return !pCsw->nStatus;
217 nResult = syncIn(
m_pInEndpoint, reinterpret_cast<uintptr_t>(pCsw), 13);
228 "USB: MSD: Reading CSW ended up failing after endpoint " 229 "halt cleared, and a mass storage reset, with status " 237 syncIn(
m_pInEndpoint, reinterpret_cast<uintptr_t>(pCsw), 13);
241 "USB: MSD: Reading CSW ended up failing after endpoint " 242 "halt cleared, with status " 250 return !pCsw->nStatus;
virtual void initialiseDriver()
Implemented by the driver class, initialises driver-specific stuff.
Endpoint * m_pInEndpoint
The endpoint used to receive input reports from the device.
virtual bool sendCommand(size_t nUnit, uintptr_t pCommand, uint8_t nCommandSize, uintptr_t pRespBuffer, uint16_t nRespBytes, bool bWrite)
bool controlRequest(uint8_t nRequestType, uint8_t nRequest, uint16_t nValue, uint16_t nIndex, uint16_t nLength=0, uintptr_t pBuffer=0)
Performs an USB control request.
UsbState m_UsbState
The current state of the device.
bool clearEndpointHalt(Endpoint *pEndpoint)
Clears a halt on the given endpoint.
Interface * m_pInterface
Interface in use.