IOUSBHIDDriverUserClient.cpp [plain text]
#include <IOKit/IOLib.h> // For IOLog()...
#include <IOKit/usb/IOUSBHIDDriver.h>
#include <IOKit/usb/IOUSBHIDDriverUserClient.h>
#include <IOKit/usb/IOUSBHIDDataQueue.h>
#define super IOUserClient
OSDefineMetaClassAndStructors(IOUSBHIDDriverUserClient, super)
bool IOUSBHIDDriverUserClient::
initWithTask(task_t owningTask, void *security_id, UInt32 type)
{
if (!super::init())
return false;
fClient = owningTask;
task_reference(fClient);
numReports = 64;
reportSize = 4;
reportQueue = (IOUSBHIDDataQueue *)0;
notifyPort = MACH_PORT_NULL;
return true;
}
#if 0 // Eric's original
bool IOUSBHIDDriverUserClient::init(IOUSBHIDDriver *driver, UInt32 numReports, UInt32 reportSize)
{
if (!driver)
{
return false;
}
fOwner = driver;
IOUSBHIDDriverUserClient::numReports = numReports; IOUSBHIDDriverUserClient::reportSize = reportSize;
reportQueue = (IOUSBHIDDataQueue *)0;
notifyPort = MACH_PORT_NULL;
return true;
}
#endif
bool IOUSBHIDDriverUserClient::
start(IOService *provider)
{
if (!super::start(provider))
return false;
fOwner = OSDynamicCast(IOUSBHIDDriver, provider);
if (fOwner && fOwner->open(this))
return true;
fOwner = 0;
return false;
}
IOReturn IOUSBHIDDriverUserClient::
clientClose(void)
{
clientDisconnect();
if (fOwner)
{ fOwner->close(this);
detach(fOwner);
fOwner = 0;
}
if (fClient) {
task_deallocate(fClient);
fClient = 0;
}
return kIOReturnSuccess;
}
#if 0 // Eric's original
IOReturn IOUSBHIDDriverUserClient::clientClose()
{
clientDisconnect();
return kIOReturnSuccess;
}
#endif
IOReturn IOUSBHIDDriverUserClient::clientDied()
{
clientDisconnect();
return kIOReturnSuccess;
}
void IOUSBHIDDriverUserClient::clientDisconnect()
{
#if 0 // IOService
if (fOwner && reportQueue)
{
fOwner->removeReportQueue(reportQueue);
reportQueue->release();
reportQueue = (IOUSBHIDDataQueue *)0;
}
#endif
return;
}
IOReturn IOUSBHIDDriverUserClient::clientMemoryForType(UInt32 type,
IOOptionBits *options,
IOMemoryDescriptor **memory)
{
#if 0 // IOService
IOReturn result = kIOReturnSuccess;
switch (type)
{
case kHIDDriverReportQueue:
reportQueue = IOUSBHIDDataQueue::withEntries(numReports, reportSize);
if (reportQueue)
{
IOMemoryDescriptor *memoryDescriptor;
memoryDescriptor = reportQueue->getMemoryDescriptor();
if (memoryDescriptor)
{
*memory = memoryDescriptor;
*options = 0;
if (notifyPort != MACH_PORT_NULL)
{
reportQueue->setNotificationPort(notifyPort);
fOwner->addReportQueue(reportQueue);
}
}
else
{
reportQueue->release();
reportQueue = (IOUSBHIDDataQueue *)0;
result = kIOReturnNoMemory;
}
}
else
{
result = kIOReturnNoMemory;
}
break;
default:
result = kIOReturnUnsupported;
break;
}
return result;
#else // IOHIDDevice
return kIOReturnNoMemory;
#endif
}
IOReturn IOUSBHIDDriverUserClient::registerNotificationPort(mach_port_t port,
UInt32 type,
UInt32 refCon)
{
#if 0 // IOService
notifyPort = port;
if (fOwner && reportQueue && (notifyPort != MACH_PORT_NULL))
{
reportQueue->setNotificationPort(notifyPort);
fOwner->addReportQueue(reportQueue);
}
return kIOReturnSuccess;
#else // IOHIDDevice
return kIOReturnNoMemory;
#endif
}
IOExternalMethod *IOUSBHIDDriverUserClient::
getTargetAndMethodForIndex(IOService **target, UInt32 index)
{
if (index < (UInt32)kUSBHIDNumMethods)
{
*target = this;
return &sMethods[index];
}
else
return NULL;
}
IOExternalMethod IOUSBHIDDriverUserClient::
sMethods[kUSBHIDNumMethods] =
{
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetReport,
kIOUCScalarIStructO,
2,
0xffffffff
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucSetReport,
kIOUCScalarIStructI,
2,
0xffffffff
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetHIDDescriptor,
kIOUCScalarIStructO,
2,
0xffffffff
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetVendorID,
kIOUCScalarIScalarO,
0,
1
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetProductID,
kIOUCScalarIScalarO,
0,
1
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetVersionNumber,
kIOUCScalarIScalarO,
0,
1
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetMaxReportSize,
kIOUCScalarIScalarO,
0,
1
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetManufacturerString,
kIOUCScalarIStructO,
1,
0xffffffff
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetProductString,
kIOUCScalarIStructO,
1,
0xffffffff
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetSerialNumberString,
kIOUCScalarIStructO,
1,
0xffffffff
},
{ NULL,
(IOMethod) &IOUSBHIDDriverUserClient::ucGetIndexedString,
kIOUCScalarIStructO,
2,
0xffffffff
},
};
IOReturn IOUSBHIDDriverUserClient::
ucGetReport(UInt32 inReportType, UInt32 inReportID, UInt8 *vInBuf, UInt32 *vInSize, void *, void *)
{
return fOwner->GetReport(inReportType, inReportID, vInBuf, vInSize);
}
IOReturn IOUSBHIDDriverUserClient::
ucSetReport(UInt32 outReportType, UInt32 outReportID, UInt8 *vOutBuf, UInt32 vOutSize, void *, void *)
{
return fOwner->SetReport(outReportType, outReportID, vOutBuf, vOutSize);
}
IOReturn IOUSBHIDDriverUserClient::
ucGetHIDDescriptor(UInt32 inDescType, UInt32 inDescIndex, void *vOutBuf, void *vOutSize, void *, void *)
{
return fOwner->GetHIDDescriptor((UInt8)inDescType, (UInt8)inDescIndex, (UInt8 *)vOutBuf, (UInt32 *)vOutSize);
}
IOReturn IOUSBHIDDriverUserClient::
ucGetVendorID(UInt32 *id, void *, void *, void *, void *, void *)
{
IOReturn err;
UInt16 vendID;
err = fOwner->GetVendorID(&vendID);
*id = vendID;
return err;
}
IOReturn IOUSBHIDDriverUserClient::
ucGetProductID(UInt32 *id, void *, void *, void *, void *, void *)
{
IOReturn err;
UInt16 prodID;
err = fOwner->GetProductID(&prodID);
*id = prodID;
return err;
}
IOReturn IOUSBHIDDriverUserClient::
ucGetVersionNumber(UInt32 *vers, void *, void *, void *, void *, void *)
{
IOReturn err;
UInt16 versNum;
err = fOwner->GetVersionNumber(&versNum);
*vers = versNum;
return err;
}
IOReturn IOUSBHIDDriverUserClient::
ucGetMaxReportSize(UInt32 *size, void *, void *, void *, void *, void *)
{
IOReturn err;
UInt32 maxSize;
err = fOwner->GetMaxReportSize(&maxSize);
*size = maxSize;
return err;
}
IOReturn IOUSBHIDDriverUserClient::
ucGetManufacturerString(UInt32 lang, UInt8 *vOutBuf, UInt32 *vOutSize, void *, void *, void *)
{
if (lang >= 0x10000)
{
IOLog(" Invalid language selector.\n");
return kIOReturnBadArgument;
}
return fOwner->GetManufacturerString(vOutBuf, vOutSize, (UInt16)lang);
}
IOReturn IOUSBHIDDriverUserClient::
ucGetProductString(UInt32 lang, UInt8 *vOutBuf, UInt32 *vOutSize, void *, void *, void *)
{
if (lang >= 0x10000)
{
IOLog(" Invalid language selector.\n");
return kIOReturnBadArgument;
}
return fOwner->GetProductString(vOutBuf, vOutSize, (UInt16)lang);
}
IOReturn IOUSBHIDDriverUserClient::
ucGetSerialNumberString(UInt32 lang, UInt8 *vOutBuf, UInt32 *vOutSize, void *, void *, void *)
{
if (lang >= 0x10000)
{
IOLog(" Invalid language selector.\n");
return kIOReturnBadArgument;
}
return fOwner->GetSerialNumberString(vOutBuf, vOutSize, (UInt16)lang);
}
IOReturn IOUSBHIDDriverUserClient::
ucGetIndexedString(UInt32 index, UInt32 lang, UInt8 *vOutBuf, UInt32 *vOutSize, void *, void *)
{
if (index >= 0x100)
{
IOLog(" Invalid string index.\n");
return kIOReturnBadArgument;
}
if (lang >= 0x10000)
{
IOLog(" Invalid language selector.\n");
return kIOReturnBadArgument;
}
return fOwner->GetIndexedString((UInt8)index, vOutBuf, vOutSize, (UInt16)lang);
}