20#include "UsbHumanInterfaceDevice.h"
21#include "pedigree/kernel/Log.h"
22#include "pedigree/kernel/panic.h"
23#include "pedigree/kernel/processor/types.h"
24#include "pedigree/kernel/utilities/PointerGuard.h"
25#include "pedigree/kernel/utilities/Vector.h"
26#include "pedigree/kernel/utilities/utility.h"
28#include "modules/drivers/common/hid/HidReport.h"
29#include "modules/system/usb/UsbConstants.h"
30#include "modules/system/usb/UsbDevice.h"
32UsbHumanInterfaceDevice::UsbHumanInterfaceDevice(
UsbDevice* pDev)
34 m_pInEndpoint(nullptr),
37 m_pInReportBuffer(nullptr),
38 m_pOldInReportBuffer(nullptr),
39 m_ReceivedInput(false) {}
41UsbHumanInterfaceDevice::~UsbHumanInterfaceDevice() {
43 panic(
"USB HID destroyed from its running interrupt callback");
54 for (
size_t i = 0; i <
m_pInterface->otherDescriptorList.count(); i++) {
61 if (!pHidDescriptor) {
62 ERROR(
"USB: HID: No HID descriptor");
68 controlRequest(
static_cast<uint8_t
>(
static_cast<uint8_t
>(UsbRequestType::Class) |
69 static_cast<uint8_t
>(UsbRequestRecipient::Interface)),
73 uint16_t nReportDescriptorSize = pHidDescriptor->nDescriptorLength;
74 uint8_t* pReportDescriptor =
static_cast<uint8_t*
>(
75 getDescriptor(0x22, 0, nReportDescriptorSize, UsbRequestRecipient::Interface));
77 if (!pReportDescriptor) {
78 ERROR(
"USB: HID: Could not read report descriptor");
86 WARNING(
"USB: HID: invalid or unsupported report descriptor");
91 for (
size_t i = 0; i <
m_pInterface->endpointList.count(); i++) {
93 if (pEndpoint->nTransferType == Endpoint::Interrupt && pEndpoint->bIn) {
101 ERROR(
"USB: HID: No Interrupt IN endpoint");
114 reinterpret_cast<uintptr_t
>(
this))) {
115 ERROR(
"USB: HID: recurring interrupt-IN submission failed");
126void UsbHumanInterfaceDevice::callback(uintptr_t pParam, ssize_t ret) {
128 if (ret > 0 &&
static_cast<size_t>(ret) <= pHid->
m_pInEndpoint->nMaxPacketSize)
129 pHid->inputHandler(ret);
132void UsbHumanInterfaceDevice::inputHandler(
size_t bytes) {
137 if (!m_ReceivedInput) {
138 m_ReceivedInput =
true;
139 NOTICE(
"USB: HID: first input report, device "
void parseDescriptor(uint8_t *pDescriptor, size_t nDescriptorLength)
Parses a HID report descriptor and stores the resulted data.
void feedInput(uint8_t *pBuffer, uint8_t *pOldBuffer, size_t nBufferSize)
Feeds the input interpreter with a new input buffer.
uint8_t m_nAddress
The current address of the device.
Interface * m_pInterface
Interface in use.
bool controlRequest(uint8_t nRequestType, uint8_t nRequest, uint16_t nValue, uint16_t nIndex, uint16_t nLength=0, uintptr_t pBuffer=0, uint32_t timeout=5000)
Performs an USB control request.
UsbState m_UsbState
The current state of the device.
DeviceDescriptor * m_pDescriptor
Device descriptor for this device.
DeviceDescriptor * getDescriptor()
Returns the device descriptor of the device.
virtual void initialiseDriver()
Implemented by the driver class, initialises driver-specific stuff.
uint8_t * m_pInReportBuffer
Input report buffer.
HidReport * m_pReport
The report instance used for input parsing.
uint8_t * m_pOldInReportBuffer
Old input report buffer.
Endpoint * m_pInEndpoint
The endpoint used to receive input reports from the device.
UsbInterruptInHandle m_InterruptIn
Owns and synchronously cancels the recurring controller callback.
MUST_USE_RESULT bool reset()
void EXPORTED_PUBLIC panic(const char *msg) NORETURN