/*
 * Copyright (c) 1998-2003 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
#ifndef _IOKIT_IOUSBDeviceClass_H
#define _IOKIT_IOUSBDeviceClass_H

#include <IOKit/usb/IOUSBLib.h>

#include "IOUSBIUnknown.h"

class IOUSBDeviceClass : public IOUSBIUnknown
{
private:
    // Disable copy constructors
    IOUSBDeviceClass(IOUSBDeviceClass &src);
    void operator =(IOUSBDeviceClass &src);

protected:
    IOUSBDeviceClass();
    virtual ~IOUSBDeviceClass();

    enum constants {
        kMaxPoolSize = 8
    };

    static IOCFPlugInInterface 		sIOCFPlugInInterfaceV1;
    static IOUSBDeviceInterface197  	sUSBDeviceInterfaceV197;

    struct InterfaceMap 		fUSBDevice;
    io_service_t 			fService;
    io_connect_t 			fConnection;
    mach_port_t 			fAsyncPort;
    CFRunLoopSourceRef 			fCFSource;
    bool 				fIsOpen;
    UInt8				fClass;
    UInt8				fSubClass;
    UInt8				fProtocol;
    UInt16				fVendor;
    UInt16				fProduct;
    UInt16				fDeviceReleaseNumber;
    UInt8				fManufacturerStringIndex;
    UInt8				fProductStringIndex;
    UInt8				fSerialNumberStringIndex;
    UInt8				fNumConfigurations;
    USBDeviceAddress			fAddress;
    UInt32				fPowerAvail;
    UInt8				fSpeed;
    UInt32				fLocationID;
    IOUSBConfigurationDescriptorPtr	*fConfigurations;
    bool				fConfigDescCacheValid;
    
public:
    static IOCFPlugInInterface **alloc();

    virtual HRESULT queryInterface(REFIID iid, void **ppv);

    virtual IOReturn probe(CFDictionaryRef propertyTable,
                           io_service_t service, SInt32 *order);
    virtual IOReturn start(CFDictionaryRef propertyTable,
                           io_service_t service);
    // No stop as such just map the deviceStop call onto close.
    virtual IOReturn CreateDeviceAsyncEventSource(CFRunLoopSourceRef *source);
    virtual CFRunLoopSourceRef GetDeviceAsyncEventSource(void);
    virtual IOReturn CreateDeviceAsyncPort(mach_port_t *port);
    virtual mach_port_t GetDeviceAsyncPort(void);
    virtual IOReturn USBDeviceOpen(bool seize);
    virtual IOReturn USBDeviceClose(void);
    virtual IOReturn GetDeviceClass(UInt8 *devClass);
    virtual IOReturn GetDeviceSubClass(UInt8 *devSubClass);
    virtual IOReturn GetDeviceProtocol(UInt8 *devProtocol);
    virtual IOReturn GetDeviceVendor(UInt16 *devVendor);
    virtual IOReturn GetDeviceProduct(UInt16 *devProduct);
    virtual IOReturn GetDeviceReleaseNumber(UInt16 *devRelNum);
    virtual IOReturn GetDeviceAddress(USBDeviceAddress *addr);
    virtual IOReturn GetDeviceBusPowerAvailable(UInt32 *powerAvailable);
    virtual IOReturn GetDeviceSpeed(UInt8 *devSpeed);
    virtual IOReturn GetNumberOfConfigurations(UInt8 *numConfig);
    virtual IOReturn GetLocationID(UInt32 *locationID);
    virtual IOReturn GetConfigurationDescriptorPtr(UInt8 configIndex, IOUSBConfigurationDescriptorPtr *desc);
    virtual IOReturn GetConfiguration(UInt8 *configNum);
    virtual IOReturn SetConfiguration(UInt8 configNum);
    virtual IOReturn GetBusFrameNumber(UInt64 *frame, AbsoluteTime *atTime);
    virtual IOReturn ResetDevice(void);
    virtual IOReturn DeviceRequest(IOUSBDevRequestTO *req);
    virtual IOReturn DeviceRequestAsync(IOUSBDevRequestTO *req, IOAsyncCallback1 callback, void *refCon);
    virtual IOReturn CreateInterfaceIterator(IOUSBFindInterfaceRequest *intReq, io_iterator_t *iter);
    // ----- new with 1.8.2
    virtual IOReturn USBDeviceSuspend(bool suspend);
    virtual IOReturn USBDeviceAbortPipeZero(void);
    virtual IOReturn USBDeviceGetManufacturerStringIndex(UInt8 *msi);
    virtual IOReturn USBDeviceGetProductStringIndex(UInt8 *psi);
    virtual IOReturn USBDeviceGetSerialNumberStringIndex(UInt8 *snsi);
    // ----- new with 1.8.7
    virtual IOReturn USBDeviceReEnumerate(UInt32 options);
    // ----- new with 1.9.7
    virtual IOReturn GetBusMicroFrameNumber(UInt64 *microFrame, AbsoluteTime *atTime);
    virtual IOReturn GetIOUSBLibVersion(NumVersion *ioUSBLibVersion, NumVersion *usbFamilyVersion);
/*
 * Routing gumf for CFPlugIn interfaces
 */
protected:

    IOReturn	CacheConfigDescriptor( void );
    
    static inline IOUSBDeviceClass *getThis(void *self)
        { return (IOUSBDeviceClass *) ((InterfaceMap *) self)->obj; };

    // Methods for routing the iocfplugin Interface v1r1
    static IOReturn deviceProbe(void *self,
                                CFDictionaryRef propertyTable,
                                io_service_t service, SInt32 *order);

    static IOReturn deviceStart(void *self,
                                CFDictionaryRef propertyTable,
                                io_service_t service);

    static IOReturn deviceStop(void *self);	// Calls close()
    static IOReturn deviceCreateDeviceAsyncEventSource(void *self, CFRunLoopSourceRef *source);
    static CFRunLoopSourceRef deviceGetDeviceAsyncEventSource(void *self);
    static IOReturn deviceCreateDeviceAsyncPort(void *self, mach_port_t *port);
    static mach_port_t deviceGetDeviceAsyncPort(void *self);
    static IOReturn deviceUSBDeviceOpen(void *self);
    static IOReturn deviceUSBDeviceClose(void *self);
    static IOReturn deviceGetDeviceClass(void *self, UInt8 *devClass);
    static IOReturn deviceGetDeviceSubClass(void *self, UInt8 *devSubClass);
    static IOReturn deviceGetDeviceProtocol(void *self, UInt8 *devProtocol);
    static IOReturn deviceGetDeviceVendor(void *self, UInt16 *devVendor);
    static IOReturn deviceGetDeviceProduct(void *self, UInt16 *devProduct);
    static IOReturn deviceGetDeviceReleaseNumber(void *self, UInt16 *devRelNum);
    static IOReturn deviceGetDeviceAddress(void *self, USBDeviceAddress *addr);
    static IOReturn deviceGetDeviceBusPowerAvailable(void *self, UInt32 *powerAvailable);
    static IOReturn deviceGetDeviceSpeed(void *self, UInt8 *devSpeed);
    static IOReturn deviceGetNumberOfConfigurations(void *self, UInt8 *numConfig);
    static IOReturn deviceGetLocationID(void *self, UInt32 *locationID);
    static IOReturn deviceGetConfigurationDescriptorPtr(void *self, UInt8 configIndex, IOUSBConfigurationDescriptorPtr *desc);
    static IOReturn deviceGetConfiguration(void *self, UInt8 *configNum);
    static IOReturn deviceSetConfiguration(void *self, UInt8 configNum);
    static IOReturn deviceGetBusFrameNumber(void *self, UInt64 *frame, AbsoluteTime *atTime);
    static IOReturn deviceResetDevice(void *self);
    static IOReturn deviceDeviceRequest(void *self, IOUSBDevRequest *req);
    static IOReturn deviceDeviceRequestAsync(void *self, IOUSBDevRequest *req, IOAsyncCallback1 callback, void *refCon);
    static IOReturn deviceCreateInterfaceIterator(void *self, IOUSBFindInterfaceRequest *intReq, io_iterator_t *iter);
    // -----added in 1.8.2
    static IOReturn deviceUSBDeviceOpenSeize(void *self);
    static IOReturn deviceDeviceRequestTO(void *self, IOUSBDevRequestTO *req);
    static IOReturn deviceDeviceRequestAsyncTO(void *self, IOUSBDevRequestTO *req, IOAsyncCallback1 callback, void *refCon);
    static IOReturn deviceUSBDeviceSuspend(void *self, Boolean suspend);
    static IOReturn deviceUSBDeviceAbortPipeZero(void *self);
    static IOReturn deviceGetManufacturerStringIndex(void *self, UInt8 *msi);
    static IOReturn deviceGetProductStringIndex(void *self, UInt8 *psi);
    static IOReturn deviceGetSerialNumberStringIndex(void *self, UInt8 *snsi);
    // -----added in 1.8.7
    static IOReturn deviceReEnumerateDevice(void *self, UInt32 options);
    // -----added in 1.9.7
    static IOReturn deviceGetBusMicroFrameNumber(void *self, UInt64 *microFrame, AbsoluteTime *atTime);
    static IOReturn deviceGetIOUSBLibVersion( void *self, NumVersion *ioUSBLibVersion, NumVersion *usbFamilyVersion);
};

#endif /* !_IOKIT_IOUSBDeviceClass_H */
