diff --git a/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp b/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp index 6805965136..80dbd314ac 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp @@ -1,20 +1,31 @@ /* - Driver for USB Human Interface Devices. - Copyright (C) 2008-2009 Michael Lotz - Distributed under the terms of the MIT license. + * Copyright 2008-2009 Michael Lotz + * Distributed under the terms of the MIT license. */ + +//! Driver for USB Human Interface Devices. + + #include "DeviceList.h" #include "Driver.h" #include "HIDDevice.h" #include "ProtocolHandler.h" #include +#include + #include #include #include +struct device_cookie { + ProtocolHandler* handler; + uint32 cookie; +}; + + int32 api_version = B_CUR_DRIVER_API_VERSION; usb_module_info *gUSBModule = NULL; DeviceList *gDeviceList = NULL; @@ -163,21 +174,34 @@ usb_hid_device_removed(void *cookie) static status_t -usb_hid_open(const char *name, uint32 flags, void **cookie) +usb_hid_open(const char *name, uint32 flags, void **_cookie) { - TRACE("open(%s, %lu, %p)\n", name, flags, cookie); - mutex_lock(&sDriverLock); + TRACE("open(%s, %lu, %p)\n", name, flags, _cookie); + + device_cookie *cookie = new(std::nothrow) device_cookie(); + if (cookie == NULL) + return B_NO_MEMORY; + + MutexLocker locker(sDriverLock); ProtocolHandler *handler = (ProtocolHandler *)gDeviceList->FindDevice(name); - if (handler == NULL) { - mutex_unlock(&sDriverLock); - return B_ENTRY_NOT_FOUND; + TRACE(" name %s: handler %p\n", name, handler); + + cookie->handler = handler; + cookie->cookie = 0; + + status_t result = handler == NULL ? B_ENTRY_NOT_FOUND : B_OK; + if (result == B_OK) + result = handler->Open(flags, &cookie->cookie); + + if (result != B_OK) { + delete cookie; + return result; } - status_t result = handler->Open(flags); - *cookie = handler; - mutex_unlock(&sDriverLock); - return result; + *_cookie = cookie; + + return B_OK; } @@ -201,30 +225,34 @@ usb_hid_write(void *cookie, off_t position, const void *buffer, static status_t -usb_hid_control(void *cookie, uint32 op, void *buffer, size_t length) +usb_hid_control(void *_cookie, uint32 op, void *buffer, size_t length) { + device_cookie *cookie = (device_cookie *)_cookie; + TRACE("control(%p, %lu, %p, %lu)\n", cookie, op, buffer, length); - ProtocolHandler *handler = (ProtocolHandler *)cookie; - return handler->Control(op, buffer, length); + return cookie->handler->Control(&cookie->cookie, op, buffer, length); } static status_t -usb_hid_close(void *cookie) +usb_hid_close(void *_cookie) { + device_cookie *cookie = (device_cookie *)_cookie; + TRACE("close(%p)\n", cookie); - ProtocolHandler *handler = (ProtocolHandler *)cookie; - return handler->Close(); + return cookie->handler->Close(); } static status_t -usb_hid_free(void *cookie) +usb_hid_free(void *_cookie) { + device_cookie *cookie = (device_cookie *)_cookie; TRACE("free(%p)\n", cookie); + mutex_lock(&sDriverLock); - HIDDevice *device = ((ProtocolHandler *)cookie)->Device(); + HIDDevice *device = cookie->handler->Device(); if (device->IsOpen()) { // another handler of this device is still open so we can't free it } else if (device->IsRemoved()) { @@ -242,6 +270,8 @@ usb_hid_free(void *cookie) } mutex_unlock(&sDriverLock); + + delete cookie; return B_OK; } diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp index 32ad323471..6dc451ad92 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp @@ -1,7 +1,12 @@ /* - Copyright (C) 2008-2009 Michael Lotz - Distributed under the terms of the MIT license. -*/ + * Copyright 2008-2009 Michael Lotz + * Distributed under the terms of the MIT license. + */ + + +//! Driver for USB Human Interface Devices. + + #include "Driver.h" #include "HIDDevice.h" #include "HIDReport.h" diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.h b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.h index b3aa051899..8c989c63da 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.h +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.h @@ -1,17 +1,19 @@ /* - Driver for USB Human Interface Devices. - Copyright (C) 2008 Michael Lotz - Distributed under the terms of the MIT license. -*/ + * Copyright 2008 Michael Lotz + * Distributed under the terms of the MIT license. + */ #ifndef USB_HID_DEVICE_H #define USB_HID_DEVICE_H + #include "HIDParser.h" #include + class ProtocolHandler; + class HIDDevice { public: HIDDevice(usb_device device, @@ -19,50 +21,52 @@ public: size_t interfaceIndex); ~HIDDevice(); - void SetParentCookie(int32 cookie); - int32 ParentCookie() { return fParentCookie; }; + void SetParentCookie(int32 cookie); + int32 ParentCookie() { return fParentCookie; }; - status_t InitCheck() { return fStatus; }; + status_t InitCheck() { return fStatus; }; - bool IsOpen() { return fOpenCount > 0; }; - status_t Open(ProtocolHandler *handler, uint32 flags); - status_t Close(ProtocolHandler *handler); + bool IsOpen() { return fOpenCount > 0; }; + status_t Open(ProtocolHandler *handler, uint32 flags); + status_t Close(ProtocolHandler *handler); - void Removed(); - bool IsRemoved() { return fRemoved; }; + void Removed(); + bool IsRemoved() { return fRemoved; }; - status_t MaybeScheduleTransfer(); + status_t MaybeScheduleTransfer(); - status_t SendReport(HIDReport *report); + status_t SendReport(HIDReport *report); - HIDParser * Parser() { return &fParser; }; - ProtocolHandler * ProtocolHandlerAt(uint32 index); + HIDParser * Parser() { return &fParser; }; + ProtocolHandler * ProtocolHandlerAt(uint32 index); - // only to be used for the kernel debugger information - usb_pipe InterruptPipe() { return fInterruptPipe; }; + // only to be used for the kernel debugger information + usb_pipe InterruptPipe() { return fInterruptPipe; }; private: -static void _TransferCallback(void *cookie, + static void _TransferCallback(void *cookie, status_t status, void *data, size_t actualLength); - status_t fStatus; - usb_device fDevice; - usb_pipe fInterruptPipe; - size_t fInterfaceIndex; +private: + status_t fStatus; + usb_device fDevice; + usb_pipe fInterruptPipe; + size_t fInterfaceIndex; - int32 fTransferScheduled; - size_t fTransferBufferSize; - uint8 * fTransferBuffer; + int32 fTransferScheduled; + size_t fTransferBufferSize; + uint8 * fTransferBuffer; - int32 fParentCookie; - int32 fOpenCount; - bool fRemoved; + int32 fParentCookie; + int32 fOpenCount; + bool fRemoved; - HIDParser fParser; + HIDParser fParser; - uint32 fProtocolHandlerCount; - ProtocolHandler ** fProtocolHandlers; + uint32 fProtocolHandlerCount; + ProtocolHandler ** fProtocolHandlers; }; + #endif // USB_HID_DEVICE_H diff --git a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp index b8daa14b1e..dfb43f69eb 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp @@ -26,6 +26,8 @@ #define RIGHT_ALT_KEY 0x40 #define ALT_KEYS (LEFT_ALT_KEY | RIGHT_ALT_KEY) +#define KEYBOARD_FLAG_DEBUGGER 0x01 + static usb_id sDebugKeyboardPipe = 0; static size_t sDebugKeyboardReportSize = 0; @@ -57,7 +59,8 @@ KeyboardDevice::KeyboardDevice(HIDReport *inputReport, HIDReport *outputReport) fModifierCount(0), fLastModifiers(0), fCurrentKeys(NULL), - fLastKeys(NULL) + fLastKeys(NULL), + fHasDebugReader(false) { // find modifiers and keys for (uint32 i = 0; i < inputReport->CountItems(); i++) { @@ -197,9 +200,9 @@ KeyboardDevice::AddHandler(HIDDevice *device, HIDReport *input) status_t -KeyboardDevice::Open(uint32 flags) +KeyboardDevice::Open(uint32 flags, uint32 *cookie) { - status_t status = ProtocolHandler::Open(flags); + status_t status = ProtocolHandler::Open(flags, cookie); if (status != B_OK) { TRACE_ALWAYS("keyboard device failed to open: %s\n", strerror(status)); @@ -213,7 +216,7 @@ KeyboardDevice::Open(uint32 flags) status_t -KeyboardDevice::Control(uint32 op, void *buffer, size_t length) +KeyboardDevice::Control(uint32 *cookie, uint32 op, void *buffer, size_t length) { switch (op) { case KB_READ: @@ -286,6 +289,14 @@ KeyboardDevice::Control(uint32 op, void *buffer, size_t length) != B_OK) return B_BAD_ADDRESS; return B_OK; + + case KB_SET_DEBUG_READER: + if (fHasDebugReader) + return B_BUSY; + + *cookie |= KEYBOARD_FLAG_DEBUGGER; + fHasDebugReader = true; + return B_OK; } TRACE_ALWAYS("keyboard device unhandled control 0x%08lx\n", op); diff --git a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.h b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.h index 0e8e113976..d8742ff7b9 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.h +++ b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.h @@ -1,53 +1,62 @@ /* - Copyright (C) 2008-2009 Michael Lotz - Distributed under the terms of the MIT license. -*/ + * Copyright 2008-2009 Michael Lotz + * Distributed under the terms of the MIT license. + */ #ifndef USB_KEYBOARD_DEVICE_H #define USB_KEYBOARD_DEVICE_H + #include "ProtocolHandler.h" + +class HIDReportItem; + + #define MAX_MODIFIERS 16 #define MAX_KEYS 16 #define MAX_LEDS 3 -class HIDReportItem; class KeyboardDevice : public ProtocolHandler { public: KeyboardDevice(HIDReport *inputReport, HIDReport *outputReport); -virtual ~KeyboardDevice(); + virtual ~KeyboardDevice(); -static ProtocolHandler * AddHandler(HIDDevice *device, + static ProtocolHandler * AddHandler(HIDDevice *device, HIDReport *input); -virtual status_t Open(uint32 flags); -virtual status_t Control(uint32 op, void *buffer, size_t length); + virtual status_t Open(uint32 flags, uint32 *cookie); + virtual status_t Control(uint32 *cookie, uint32 op, void *buffer, + size_t length); private: - void _WriteKey(uint32 key, bool down); - status_t _SetLEDs(uint8 *data); - status_t _ReadReport(bigtime_t timeout); + void _WriteKey(uint32 key, bool down); + status_t _SetLEDs(uint8 *data); + status_t _ReadReport(bigtime_t timeout); - HIDReport * fInputReport; - HIDReport * fOutputReport; +private: + HIDReport * fInputReport; + HIDReport * fOutputReport; - HIDReportItem * fModifiers[MAX_MODIFIERS]; - HIDReportItem * fKeys[MAX_KEYS]; - HIDReportItem * fLEDs[MAX_LEDS]; + HIDReportItem * fModifiers[MAX_MODIFIERS]; + HIDReportItem * fKeys[MAX_KEYS]; + HIDReportItem * fLEDs[MAX_LEDS]; - bigtime_t fRepeatDelay; - bigtime_t fRepeatRate; - bigtime_t fCurrentRepeatDelay; - uint32 fCurrentRepeatKey; + bigtime_t fRepeatDelay; + bigtime_t fRepeatRate; + bigtime_t fCurrentRepeatDelay; + uint32 fCurrentRepeatKey; - uint32 fKeyCount; - uint32 fModifierCount; + uint32 fKeyCount; + uint32 fModifierCount; - uint8 fLastModifiers; - uint16 * fCurrentKeys; - uint16 * fLastKeys; + uint8 fLastModifiers; + uint16 * fCurrentKeys; + uint16 * fLastKeys; + + bool fHasDebugReader; }; + #endif // USB_KEYBOARD_DEVICE_H diff --git a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp index 3adab08ca1..782358977a 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp @@ -75,7 +75,7 @@ MouseDevice::AddHandler(HIDDevice *device, HIDReport *report) status_t -MouseDevice::Control(uint32 op, void *buffer, size_t length) +MouseDevice::Control(uint32 *cookie, uint32 op, void *buffer, size_t length) { switch (op) { case MS_READ: diff --git a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.h b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.h index 66e621ddc6..67c89391ae 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.h +++ b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.h @@ -1,45 +1,51 @@ /* - Copyright (C) 2008-2009 Michael Lotz - Distributed under the terms of the MIT license. -*/ + * Copyright 2008-2009 Michael Lotz + * Distributed under the terms of the MIT license. + */ #ifndef USB_MOUSE_DEVICE_H #define USB_MOUSE_DEVICE_H -#include -#ifndef B_MAX_MOUSE_BUTTONS -#define B_MAX_MOUSE_BUTTONS 8 -#endif +#include #include "ProtocolHandler.h" + class HIDReportItem; + +#ifndef B_MAX_MOUSE_BUTTONS +# define B_MAX_MOUSE_BUTTONS 8 +#endif + + class MouseDevice : public ProtocolHandler { public: MouseDevice(HIDReport *report, HIDReportItem *xAxis, HIDReportItem *yAxis); -static ProtocolHandler * AddHandler(HIDDevice *device, + static ProtocolHandler * AddHandler(HIDDevice *device, HIDReport *report); -virtual status_t Control(uint32 op, void *buffer, size_t length); + virtual status_t Control(uint32 *cookie, uint32 op, void *buffer, + size_t length); private: - status_t _ReadReport(); + status_t _ReadReport(); - HIDReport * fReport; +private: + HIDReport * fReport; - HIDReportItem * fXAxis; - HIDReportItem * fYAxis; - HIDReportItem * fWheel; - HIDReportItem * fButtons[B_MAX_MOUSE_BUTTONS]; + HIDReportItem * fXAxis; + HIDReportItem * fYAxis; + HIDReportItem * fWheel; + HIDReportItem * fButtons[B_MAX_MOUSE_BUTTONS]; - uint32 fLastButtons; - uint32 fClickCount; - bigtime_t fLastClickTime; - bigtime_t fClickSpeed; - uint32 fMaxButtons; + uint32 fLastButtons; + uint32 fClickCount; + bigtime_t fLastClickTime; + bigtime_t fClickSpeed; + uint32 fMaxButtons; }; #endif // USB_MOUSE_DEVICE_H diff --git a/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.cpp b/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.cpp index 3be535cb09..f092d6903a 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.cpp @@ -3,6 +3,7 @@ * Distributed under the terms of the MIT License. */ + #include #include @@ -103,7 +104,7 @@ ProtocolHandler::AddHandlers(HIDDevice *device, ProtocolHandler ***handlerList, status_t -ProtocolHandler::Open(uint32 flags) +ProtocolHandler::Open(uint32 flags, uint32 *cookie) { return fDevice->Open(this, flags); } @@ -117,7 +118,7 @@ ProtocolHandler::Close() status_t -ProtocolHandler::Control(uint32 op, void *buffer, size_t length) +ProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer, size_t length) { TRACE_ALWAYS("control on base class\n"); return B_ERROR; diff --git a/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.h b/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.h index 6a20e10f98..bc5fec8769 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.h +++ b/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.h @@ -5,48 +5,53 @@ #ifndef PROTOCOL_HANDLER_H #define PROTOCOL_HANDLER_H + #include + class HIDDevice; class HIDReport; + class ProtocolHandler { public: ProtocolHandler(HIDDevice *device, const char *basePath, size_t ringBufferSize); -virtual ~ProtocolHandler(); + virtual ~ProtocolHandler(); - status_t InitCheck() { return fStatus; }; + status_t InitCheck() { return fStatus; }; - HIDDevice * Device() { return fDevice; }; + HIDDevice * Device() { return fDevice; }; - const char * BasePath() { return fBasePath; }; - void SetPublishPath(char *publishPath); - const char * PublishPath() { return fPublishPath; }; + const char * BasePath() { return fBasePath; }; + void SetPublishPath(char *publishPath); + const char * PublishPath() { return fPublishPath; }; -static void AddHandlers(HIDDevice *device, + static void AddHandlers(HIDDevice *device, ProtocolHandler ***handlerList, uint32 *handlerCount); -virtual status_t Open(uint32 flags); -virtual status_t Close(); + virtual status_t Open(uint32 flags, uint32 *cookie); + virtual status_t Close(); -virtual status_t Control(uint32 op, void *buffer, size_t length); + virtual status_t Control(uint32 *cookie, uint32 op, void *buffer, + size_t length); - int32 RingBufferReadable(); - status_t RingBufferRead(void *buffer, size_t length); - status_t RingBufferWrite(const void *buffer, + int32 RingBufferReadable(); + status_t RingBufferRead(void *buffer, size_t length); + status_t RingBufferWrite(const void *buffer, size_t length); protected: - status_t fStatus; + status_t fStatus; private: - HIDDevice * fDevice; - const char * fBasePath; - char * fPublishPath; - struct ring_buffer * fRingBuffer; + HIDDevice * fDevice; + const char * fBasePath; + char * fPublishPath; + struct ring_buffer *fRingBuffer; }; + #endif // PROTOCOL_HANDLER_H