#include <IOKit/usb/IOUSBHostDevice.h>
IOKit/usb/IOUSBHostDevice.h
@header IOUSBHostDevice.h
@brief IOUSBHostDevice is an IOService representing a USB device.
@discussion
<h3>Session Management</h3>
A driver that has successfully matched on an IOUSBHostDevice is able to take ownership of the device by calling the <code>open</code> method defined by IOService on the IOUSBHostDevice. Once <code>open</code> has completed successfully, the driver has an open session, and may use the deviceRequest interface to send control requests, and the setConfiguration interface to create or destroy child IOUSBHostInterface services.
When the driver is finished with control of the IOUSBHostDevice, it must call <code>close</code> to end its session. Calling <code>close</code> will synchronously abort that session's outstanding IO on the control endpoint. If the device is terminating for any reason, such as being unplugged, the driver must call <code>close</code> on the IOUSBHostDevice, or termination will be blocked and the port will not register newly attached devices for matching. The willTerminate call into the driver is the recommended location to call <code>close</code>.
Drivers that match on an IOUSBHostInterface service do not need to open a session to the IOUSBHostDevice, as the IOUSBHostInterface will open a session to the IOUSBHostDevice on the driver's behalf.
<h3>deviceRequest Interface</h3>
The <code>deviceRequest</code> methods are used to send control requests to the device's default endpoint. The <code>deviceRequest</code> methods may not be used for the following standard requests:
<ul>
<li>CLEAR_FEATURE ENDPOINT_HALT (USB 2.0 9.4.1) - Use <code>IOUSBHostPipe::clearStall</code> to send this request</li>
<li>SET_ADDRESS (USB 2.0 9.4.6)</li>
<li>SET_CONFIGURATION (USB 2.0 9.4.7) - Use <code>setConfiguration</code> to send this request</li>
<li>SET_INTERFACE (USB 2.0 9.4.10) - Use <code>IOUSBHostInterface::selectAlternateSetting</code> to send this request</li>
</ul>
<h3>IOUSBDevice Migration</h3>
IOUSBHostDevice serves as a replacement for IOUSBDevice. Clients that previously matched on IOUSBDevice can use the following guide to convert to IOUSBHostDevice.
<code>virtual UInt16 IOUSBDevice::GetbcdUSB();</code><br>
Replacement: <code>USBToHost16(getDeviceDescriptor()->bcdUSB);</code>
<code>virtual UInt8 IOUSBDevice::GetDeviceClass();</code><br>
Replacement: <code>getDeviceDescriptor()->bDeviceClass;</code>
<code>virtual UInt8 IOUSBDevice::GetDeviceSubClass();</code><br>
Replacement: <code>getDeviceDescriptor()->bDeviceSubClass</code>
<code>virtual UInt8 IOUSBDevice::GetProtocol();</code><br>
Replacement: <code>getDeviceDescriptor()->bDeviceProtocol</code>
<code>virtual UInt8 IOUSBDevice::GetMaxPacketSize();</code><br>
Replacement: <code>getDeviceDescriptor->bMaxPacketSize0</code>
<code>virtual UInt16 IOUSBDevice::GetVendorID();</code><br>
Replacement: <code>USBToHost16(getDeviceDescriptor()->idVendor)</code>
<code>virtual UInt16 IOUSBDevice::GetProductID();</code><br>
Replacement: <code>USBToHost16(getDeviceDescriptor()->idProduct)</code>
<code>virtual UInt16 IOUSBDevice::GetDeviceRelease();</code><br>
Replacement: <code>USBToHost16(getDeviceDescriptor()->bcdDevice)</code>
<code>virtual UInt8 IOUSBDevice::GetNumConfigurations();</code><br>
Replacement: <code>getDeviceDescriptor()->bNumConfigurations</code>
<code>virtual UInt8 IOUSBDevice::GetManufacturerStringIndex();</code><br>
Replacement: <code>getDeviceDescriptor()->iManufacturer</code>
<code>virtual UInt8 IOUSBDevice::GetProductStringIndex();</code><br>
Replacement: <code>getDeviceDescriptor()->iProduct</code>
<code>virtual UInt8 IOUSBDevice::GetSerialNumberStringIndex();</code><br>
Replacement: <code>getDeviceDescriptor()->iSerialNumber</code>
<code>virtual IOReturn IOUSBDevice::FindNextInterfaceDescriptor(const IOUSBConfigurationDescriptor*, const IOUSBInterfaceDescriptor*, const IOUSBFindInterfaceRequest*, IOUSBInterfaceDescriptor**);</code><br>
Replacement:<br>
<pre>ConfigurationDescriptor* confDesc = getConfigurationDescriptor();
InterfaceDescriptor* intDesc = NULL;
while((intDesc = StandardUSB::getNextInterfaceDescriptor(confDesc, intDesc)) != NULL)
{
if(intDesc->bInterfaceClass == kMyClass)
{
break;
}
}</pre>
<code>virtual const IOUSBConfigurationDescriptor* IOUSBDevice::GetCachedConfigurationDescriptor(UInt8 configIndex);</code><br>
<code>virtual const IOUSBConfigurationDescriptor* IOUSBDevice::GetFullConfigurationDescriptor(UInt8 configIndex);</code><br>
Replacement: <code>getConfigurationDescriptor(configIndex)</code>
<code>virtual IOReturn IOUSBDevice::GetConfigurationDescriptor(UInt8 configValue, void* data, UInt32 len);</code><br>
Replacement: <code>getConfigurationDescriptorWithValue(configValue);</code>
<code>virtual IOUSBHostInterface* IOUSBDevice::FindNextInterface(IOUSBHostInterface*, IOUSBFindInterfaceRequest* request);</code><br>
<code>virtual OSIterator* IOUSBDevice::CreateInterfaceIterator(IOUSBFindInterfaceRequest* request);</code><br>
Replacement:<br>
<pre>OSIterator* iterator = _device->getChildIterator(gIOServicePlane);
OSObject* candidate = NULL;
while(iterator != NULL && (candidate = iterator->getNextObject()) != NULL)
{
IOUSBHostInterface* interfaceCandidate = OSDynamicCast(IOUSBHostInterface, candidate);
if( interfaceCandidate != NULL
&& interfaceCandidate->getInterfaceDescriptor()->bInterfaceClass == kMyClass)
{
_interface = interfaceCandidate;
break;
}
}
OSSafeReleaseNULL(iterator);</pre>
<code>virtual IOReturn IOUSBDevice::SetConfiguration(IOService*, UInt8, bool);</code><br>
Replacement: <code>setConfiguration(configNumber, startMatchingInterfaces);</code>
<code>virtual UInt8 IOUSBDevice::GetSpeed();</code><br>
Replacement: <code>getSpeed();</code>
<code>virtual IOUSBController* IOUSBDevice::GetBus();</code><br>
Replacement: The controller cannot be directly accessed. Use <code>getFrameNumber(...)</code> and <code>createIOBuffer(...)</code> instead.
<code>virtual UInt32 IOUSBDevice::GetBusPowerAvailable();</code><br>
Replacement: <code>allocateDownstreamBusCurrent(...);</code>
<code>virtual IOReturn IOUSBDevice::DeviceRequest(IOUSBDevRequest*, IOUSBCompletion*);<br>
virtual IOReturn IOUSBDevice::DeviceRequest(IOUSBDevRequestDesc*, IOUSBCompletion*);<br>
virtual IOReturn IOUSBDevice::DeviceRequest(IOUSBDevRequest*, UInt32, UInt32, IOUSBCompletion*);<br>
virtual IOReturn IOUSBDevice::DeviceRequest(IOUSBDevRequestDesc*, UInt32, UInt32, IOUSBCompletion*);<br></code>
Replacment: <code>deviceRequest(...);</code>
<code>virtual IOReturn IOUSBDevice::GetConfiguration(UInt8*);</code><br>
Replacment:
<pre>uint8_t configNumber = 0;
StandardUSB::DeviceRequest request;
request.bmRequestType = makeDeviceRequestbmRequestType(kRequestDirectionIn, kRequestTypeStandard, kRequestRecipientDevice);
request.bRequest = kDeviceRequestGetConfiguration;
request.wValue = 0;
request.wIndex = 0;
request.wLength = sizeof(configNumber);
uint32_t bytesTransferred = 0;
deviceRequest(this, request, &configNumber, bytesTransferred, kUSBHostStandardRequestCompletionTimeout);</pre>
<code>virtual IOReturn IOUSBDevice::GetDeviceStatus(USBStatus*);</code><br>
Replacement:
<pre>uint16_t status = 0;
StandardUSB::DeviceRequest request;
request.bmRequestType = makeDeviceRequestbmRequestType(kRequestDirectionIn, kRequestTypeStandard, kRequestRecipientDevice);
request.bRequest = kDeviceRequestGetStatus;
request.wValue = 0;
request.wIndex = 0;
request.wLength = sizeof(status);
uint32_t bytesTransferred = 0;
deviceRequest(this, request, &status, bytesTransferred, kUSBHostStandardRequestCompletionTimeout);</pre>
<code>virtual IOUSBPipe* IOUSBDevice::GetPipeZero();</code><br>
Replacement: The IOUSBHostPipe representing the default control endpoint is not accessible. Use <code>deviceRequest(...)</code> and <code>abortDeviceRequests(...)</code> interfaces to interact with the default control endpoint.
<code>virtual IOReturn IOUSBDevice::GetStringDescriptor(UInt8, char*, int, UInt16);</code><br>
Replacement:
<pre>char stringBuffer[256] = { 0 };
size_t stringLength = sizeof(stringBuffer);
const StringDescriptor* stringDescriptor = getStringDescriptor(index);
if( stringDescriptor != NULL
&& stringDescriptor->bLength > StandardUSB::kDescriptorSize)
{
StandardUB::stringDescriptorToUTF8(stringDescriptor, stringBuffer, stringLength);
}</pre>
<code>virtual const IOUSBDescriptorHeader* IOUSBDevice::FindNextDescriptor(const void*, UInt8);</code><br>
Replacement: <code>StandardUSB::getNextDescriptorWithType(getConfigurationDescriptor(), currentDescriptor, descriptorType);</code>
<code>virtual IOReturn IOUSBDevice::SuspendDevice(bool);</code><br>
Replacement: Power management should be done using the idling system described in IOUSBHostFamily.h.
<code>virtual IOReturn IOUSBDevice::ReEnumerateDevice(UInt32);</code><br>
Replacement: <code>reset();</code>
<code>virtual IOReturn IOUSBDevice::GetDeviceInformation(UInt32*);</code><br>
Replacement: <code>getPortStatus();</code>
<code>virtual UInt32 IOUSBDevice::RequestExtraPower(UInt32, UInt32);<br>
virtual IOReturn IOUSBDevice::ReturnExtraPower(UInt32, UInt32);</code><br>
Replacement: <code>allocateDownstreamBusCurrent(...);</code>
<code>virtual tUSBHostDeviceAddress IOUSBDevice::GetAddress(void);</code><br>
Replacement: <code>getAddress();</code>
<code>virtual IOReturn IOUSBDevice::ResetDevice();<br>
virtual UInt32 IOUSBDevice::GetExtraPowerAllocated(UInt32);<br>
void IOUSBDevice::SetBusPowerAvailable(UInt32);</code><br>
Replacement: none
macroIOUSBHostFamily_IOUSBHostDevice_h
#define IOUSBHostFamily_IOUSBHostDevice_h
macroTARGET_OS_HAS_USBDRIVERKIT_IOUSBHOSTDEVICE
#define TARGET_OS_HAS_USBDRIVERKIT_IOUSBHOSTDEVICE __has_include(<USBDriverKit/IOUSBHostDevice.h>)
macrokUSBHostDeviceForceSuspend
#define kUSBHostDeviceForceSuspend "kUSBHostDeviceForceSuspend"