* Prepared driver for the implementation of the debugger mode: there is now a
uint32 cookie that is saved per file handle and passed to the ProtocolHandler objects. * Beware that the output of the driver no longer shows the handler as pointer, but the internal device cookie. * Added handling of KB_SET_DEBUG_READER to the KeyboardDevice class (it just doesn't do anything with that). * Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36274 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1888e2289d
commit
48450caac5
@ -1,20 +1,31 @@
|
||||
/*
|
||||
Driver for USB Human Interface Devices.
|
||||
Copyright (C) 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
Distributed under the terms of the MIT license.
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* 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 <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,12 @@
|
||||
/*
|
||||
Copyright (C) 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
Distributed under the terms of the MIT license.
|
||||
*/
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
|
||||
//! Driver for USB Human Interface Devices.
|
||||
|
||||
|
||||
#include "Driver.h"
|
||||
#include "HIDDevice.h"
|
||||
#include "HIDReport.h"
|
||||
|
@ -1,17 +1,19 @@
|
||||
/*
|
||||
Driver for USB Human Interface Devices.
|
||||
Copyright (C) 2008 Michael Lotz <mmlr@mlotz.ch>
|
||||
Distributed under the terms of the MIT license.
|
||||
*/
|
||||
* Copyright 2008 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef USB_HID_DEVICE_H
|
||||
#define USB_HID_DEVICE_H
|
||||
|
||||
|
||||
#include "HIDParser.h"
|
||||
|
||||
#include <USB3.h>
|
||||
|
||||
|
||||
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
|
||||
|
@ -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);
|
||||
|
@ -1,53 +1,62 @@
|
||||
/*
|
||||
Copyright (C) 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
Distributed under the terms of the MIT license.
|
||||
*/
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* 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
|
||||
|
@ -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:
|
||||
|
@ -1,45 +1,51 @@
|
||||
/*
|
||||
Copyright (C) 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
Distributed under the terms of the MIT license.
|
||||
*/
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef USB_MOUSE_DEVICE_H
|
||||
#define USB_MOUSE_DEVICE_H
|
||||
|
||||
#include <InterfaceDefs.h>
|
||||
|
||||
#ifndef B_MAX_MOUSE_BUTTONS
|
||||
#define B_MAX_MOUSE_BUTTONS 8
|
||||
#endif
|
||||
#include <InterfaceDefs.h>
|
||||
|
||||
#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
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ring_buffer.h>
|
||||
|
||||
@ -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;
|
||||
|
@ -5,48 +5,53 @@
|
||||
#ifndef PROTOCOL_HANDLER_H
|
||||
#define PROTOCOL_HANDLER_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user