You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1185 lines
31 KiB
1185 lines
31 KiB
/*++
|
|
|
|
Copyright (c) 1999, 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
usbuhci.h
|
|
|
|
Abstract:
|
|
|
|
|
|
|
|
Environment:
|
|
|
|
Kernel & user mode
|
|
|
|
Revision History:
|
|
|
|
1-1-00 : created
|
|
|
|
--*/
|
|
|
|
#ifndef __USBUHCI_H__
|
|
#define __USBUHCI_H__
|
|
|
|
#define FIXPIIX4
|
|
|
|
#define SOF_TD_COUNT 8
|
|
|
|
#define ANY_VIA(dd) ((dd)->ControllerFlavor >= UHCI_VIA)
|
|
|
|
#define MASK_CHANGE_BITS(p)\
|
|
do {\
|
|
(p).PortEnableChange = 0;\
|
|
(p).PortConnectChange = 0;\
|
|
} while (0);
|
|
|
|
/*
|
|
define resource consumption for endpoints types
|
|
*/
|
|
|
|
#define T_64K 0x10000
|
|
#define T_16K 0x4000
|
|
#define T_4K 0x1000
|
|
|
|
|
|
// Control:
|
|
// largest possible transfer for control is 64k
|
|
// therefore we support up to 2 transfers of this
|
|
// size in HW. Most control transfers are much
|
|
// smaller than this.
|
|
// NOTE: we MUST support at least one 64k transfer in
|
|
// HW since a single control transfer cannot be
|
|
// broken up.
|
|
|
|
|
|
//#define MAX_CONTROL_TRANSFER_SIZE T_4K
|
|
#define MAX_ASYNC_PACKET_SIZE 64
|
|
//#define MAX_CONTROL_DOUBLE_BUFFERS MAX_CONTROL_TRANSFER_SIZE/PAGE_SIZE
|
|
//#define TDS_PER_CONTROL_ENDPOINT (MAX_CONTROL_TRANSFER_SIZE/MAX_CONTROL_PACKET_SIZE+2) // 2 EXTRA FOR SETUP AND STATUS
|
|
|
|
|
|
// Bulk:
|
|
|
|
// bugbug temprarily set to 64k
|
|
#define MAX_BULK_TRANSFER_SIZE T_4K
|
|
//#define MAX_BULK_TRANSFER_SIZE T_4K // T_16K // T_64K
|
|
//#define MAX_BULK_PACKET_SIZE 64
|
|
#define MAX_BULK_DOUBLE_BUFFERS MAX_BULK_TRANSFER_SIZE/PAGE_SIZE
|
|
#define TDS_PER_BULK_ENDPOINT (MAX_BULK_TRANSFER_SIZE/MAX_BULK_PACKET_SIZE)
|
|
|
|
// Interrupt:
|
|
|
|
//#define MAX_INTERRUPT_TRANSFER_SIZE T_4K // T_16K
|
|
//#define MAX_INTERRUPT_PACKET_SIZE 64
|
|
//#define MAX_INTERRUPT_DOUBLE_BUFFERS MAX_INTERRUPT_TRANSFER_SIZE/PAGE_SIZE
|
|
//#define TDS_PER_INTERRUPT_ENDPOINT (MAX_INTERRUPT_TRANSFER_SIZE/MAX_INTERRUPT_PACKET_SIZE)
|
|
#define MAX_INTERRUPT_TDS_PER_TRANSFER 8
|
|
|
|
// Isochronous:
|
|
#define MAX_ISOCH_TRANSFER_SIZE T_64K
|
|
#define MAX_ISOCH_PACKET_SIZE 1023
|
|
//#define MAX_ISOCH_DOUBLE_BUFFERS MAX_ISOCH_TRANSFER_SIZE/PAGE_SIZE
|
|
//#define TDS_PER_ISOCH_ENDPOINT 1024
|
|
|
|
// Maximum Polling Interval we support for interrupt (ms)
|
|
#define MAX_INTERVAL 32
|
|
#define MAX_INTERVAL_MASK(i) (i&0x1f)
|
|
|
|
// default size of frame list
|
|
#define UHCI_MAX_FRAME 1024
|
|
#define ACTUAL_FRAME(f) ((f)&0x000003FF)
|
|
|
|
//
|
|
// These values index in to the interrupt QH list
|
|
//
|
|
#define QH_INTERRUPT_1ms 0
|
|
#define QH_INTERRUPT_2ms 1
|
|
#define QH_INTERRUPT_4ms 3
|
|
#define QH_INTERRUPT_8ms 7
|
|
#define QH_INTERRUPT_16ms 15
|
|
#define QH_INTERRUPT_32ms 31
|
|
#define QH_INTERRUPT_INDEX(x) (x)-1
|
|
|
|
#define NO_INTERRUPT_INTERVALS 6
|
|
#define NO_INTERRUPT_QH_LISTS 63
|
|
|
|
// debug signatures
|
|
#define SIG_HCD_IQH 'qi01'
|
|
#define SIG_HCD_CQH 'qa01'
|
|
#define SIG_HCD_BQH 'qb01'
|
|
#define SIG_HCD_QH 'hq01'
|
|
#define SIG_HCD_DQH 'qd01'
|
|
#define SIG_HCD_TD 'dt01'
|
|
#define SIG_HCD_RTD 'dtlr'
|
|
#define SIG_HCD_SOFTD 'dtos'
|
|
#define SIG_HCD_ADB 'bd01'
|
|
#define SIG_HCD_IDB 'id01'
|
|
#define SIG_EP_DATA 'pe01'
|
|
#define SIG_UHCI_TRANSFER 'rt01'
|
|
#define SIG_UHCI_DD 'ichu'
|
|
|
|
// What gets returned by READ_PORT_USHORT when hardware is surprise removed.
|
|
#define UHCI_HARDWARE_GONE 0xffff
|
|
|
|
#undef PDEVICE_DATA
|
|
|
|
typedef struct _TRANSFER_CONTEXT {
|
|
|
|
ULONG Sig;
|
|
ULONG PendingTds;
|
|
PTRANSFER_PARAMETERS TransferParameters;
|
|
USBD_STATUS UsbdStatus;
|
|
ULONG BytesTransferred;
|
|
struct _ENDPOINT_DATA *EndpointData;
|
|
PMINIPORT_ISO_TRANSFER IsoTransfer;
|
|
|
|
} TRANSFER_CONTEXT, *PTRANSFER_CONTEXT;
|
|
|
|
|
|
// HCD Endpoint Descriptor (contains the HW descriptor)
|
|
|
|
// values for HCD_QUEUEHEAD_DESCRIPTOR.Flags
|
|
#define UHCI_QH_FLAG_IN_SCHEDULE 0x00000001
|
|
#define UHCI_QH_FLAG_QH_REMOVED 0x00000002
|
|
|
|
struct _ENDPOINT_DATA;
|
|
|
|
typedef struct _HCD_QUEUEHEAD_DESCRIPTOR {
|
|
HW_QUEUE_HEAD HwQH; // 2 dwords
|
|
HW_32BIT_PHYSICAL_ADDRESS PhysicalAddress;
|
|
ULONG Sig;
|
|
ULONG QhFlags;
|
|
struct _HCD_QUEUEHEAD_DESCRIPTOR *NextQh;
|
|
struct _HCD_QUEUEHEAD_DESCRIPTOR *PrevQh;
|
|
struct _ENDPOINT_DATA *EndpointData;
|
|
|
|
#ifdef _WIN64
|
|
ULONG PadTo64[4];
|
|
#else
|
|
ULONG PadTo64[8];
|
|
#endif
|
|
} HCD_QUEUEHEAD_DESCRIPTOR, *PHCD_QUEUEHEAD_DESCRIPTOR;
|
|
|
|
C_ASSERT((sizeof(HCD_QUEUEHEAD_DESCRIPTOR) == 64));
|
|
|
|
//
|
|
// HCD Transfer Descriptor (contains the HW descriptor)
|
|
//
|
|
|
|
#define ENDPOINT_DATA_PTR(p) ((struct _ENDPOINT_DATA *) (p).Pointer)
|
|
#define TRANSFER_CONTEXT_PTR(p) ((struct _TRANSFER_CONTEXT *) (p).Pointer)
|
|
#define TRANSFER_DESCRIPTOR_PTR(p) ((struct _HCD_TRANSFER_DESCRIPTOR *) (p).Pointer)
|
|
#define QH_DESCRIPTOR_PTR(p) ((struct _HCD_QUEUEHEAD_DESCRIPTOR *) (p).Pointer)
|
|
#define HW_PTR(p) ((UCHAR * ) (p).Pointer)
|
|
|
|
|
|
#define DB_FLAG_BUSY 0x00000001
|
|
|
|
typedef struct _TRANSFER_BUFFER_HEADER {
|
|
HW_32BIT_PHYSICAL_ADDRESS PhysicalAddress;
|
|
PUCHAR SystemAddress;
|
|
ULONG Sig;
|
|
ULONG Flags;
|
|
ULONG Size;
|
|
#ifdef _WIN64
|
|
ULONG PadTo32[1];
|
|
#else
|
|
ULONG PadTo32[3];
|
|
#endif
|
|
} TRANSFER_BUFFER_HEADER, *PTRANSFER_BUFFER_HEADER;
|
|
|
|
C_ASSERT((sizeof(TRANSFER_BUFFER_HEADER) == 32));
|
|
|
|
//
|
|
// NOTE: The buffer must go first, since the physical address
|
|
// depends on it. If not, you must change the init code.
|
|
//
|
|
typedef struct _ASYNC_TRANSFER_BUFFER {
|
|
UCHAR Buffer[MAX_ASYNC_PACKET_SIZE];
|
|
TRANSFER_BUFFER_HEADER;
|
|
} ASYNC_TRANSFER_BUFFER, *PASYNC_TRANSFER_BUFFER;
|
|
|
|
C_ASSERT((sizeof(ASYNC_TRANSFER_BUFFER) == 64+32));
|
|
|
|
typedef struct _ISOCH_TRANSFER_BUFFER {
|
|
UCHAR Buffer[MAX_ISOCH_PACKET_SIZE+1]; // bump it to 1024
|
|
TRANSFER_BUFFER_HEADER;
|
|
} ISOCH_TRANSFER_BUFFER, *PISOCH_TRANSFER_BUFFER;
|
|
|
|
C_ASSERT((sizeof(ISOCH_TRANSFER_BUFFER) == 1024+32));
|
|
|
|
typedef union _TRANSFER_BUFFER {
|
|
ISOCH_TRANSFER_BUFFER Isoch;
|
|
ASYNC_TRANSFER_BUFFER Async;
|
|
} TRANSFER_BUFFER, *PTRANSFER_BUFFER;
|
|
|
|
typedef struct _DOUBLE_BUFFER_LIST {
|
|
union {
|
|
ASYNC_TRANSFER_BUFFER Async[1];
|
|
ISOCH_TRANSFER_BUFFER Isoch[1];
|
|
};
|
|
} DOUBLE_BUFFER_LIST, *PDOUBLE_BUFFER_LIST;
|
|
|
|
// values for HCD_TRANSFER_DESCRIPTOR.Flags
|
|
|
|
#define TD_FLAG_BUSY 0x00000001
|
|
#define TD_FLAG_XFER 0x00000002
|
|
//#define TD_FLAG_CONTROL_STATUS 0x00000004
|
|
#define TD_FLAG_DONE 0x00000008
|
|
#define TD_FLAG_SKIP 0x00000010
|
|
#define TD_FLAG_DOUBLE_BUFFERED 0x00000020
|
|
#define TD_FLAG_ISO_QUEUED 0x00000040
|
|
#define TD_FLAG_SETUP_TD 0x00000100
|
|
#define TD_FLAG_DATA_TD 0x00000200
|
|
#define TD_FLAG_STATUS_TD 0x00000400
|
|
#define TD_FLAG_TIMEOUT_ERROR 0x00000800
|
|
|
|
typedef struct _HCD_TRANSFER_DESCRIPTOR {
|
|
HW_QUEUE_ELEMENT_TD HwTD;
|
|
HW_32BIT_PHYSICAL_ADDRESS PhysicalAddress;
|
|
ULONG Sig;
|
|
union {
|
|
PTRANSFER_CONTEXT TransferContext;
|
|
ULONG RequestFrame;
|
|
};
|
|
PMINIPORT_ISO_PACKET IsoPacket;
|
|
ULONG Flags;
|
|
struct _HCD_TRANSFER_DESCRIPTOR *NextTd;
|
|
PTRANSFER_BUFFER DoubleBuffer;
|
|
LIST_ENTRY DoneLink;
|
|
#ifdef _WIN64
|
|
ULONG PadTo128[12];
|
|
#else
|
|
ULONG PadTo64[3];
|
|
#endif
|
|
} HCD_TRANSFER_DESCRIPTOR, *PHCD_TRANSFER_DESCRIPTOR;
|
|
|
|
#ifdef _WIN64
|
|
C_ASSERT((sizeof(HCD_TRANSFER_DESCRIPTOR) == 128));
|
|
#else
|
|
C_ASSERT((sizeof(HCD_TRANSFER_DESCRIPTOR) == 64));
|
|
#endif
|
|
|
|
typedef struct _HCD_TD_LIST {
|
|
HCD_TRANSFER_DESCRIPTOR Td[1];
|
|
} HCD_TD_LIST, *PHCD_TD_LIST;
|
|
|
|
#define UHCI_EDFLAG_HALTED 0x00000001
|
|
#define UHCI_EDFLAG_SHORT_PACKET 0x00000002
|
|
#define UHCI_EDFLAG_NOHALT 0x00000004
|
|
|
|
typedef struct _ENDPOINT_DATA {
|
|
|
|
ULONG Sig;
|
|
ULONG Flags;
|
|
ENDPOINT_PARAMETERS Parameters;
|
|
PHCD_QUEUEHEAD_DESCRIPTOR QueueHead;
|
|
ULONG PendingTransfers;
|
|
ULONG MaxPendingTransfers;
|
|
|
|
PHCD_TRANSFER_DESCRIPTOR TailTd;
|
|
PHCD_TRANSFER_DESCRIPTOR HeadTd;
|
|
|
|
//
|
|
// Transfer descriptor cache.
|
|
//
|
|
PHCD_TD_LIST TdList;
|
|
ULONG TdCount;
|
|
ULONG TdLastAllocced;
|
|
ULONG TdsUsed;
|
|
|
|
//
|
|
// Double buffer cache.
|
|
//
|
|
PDOUBLE_BUFFER_LIST DbList;
|
|
ULONG DbCount;
|
|
ULONG DbLastAllocced;
|
|
ULONG DbsUsed;
|
|
|
|
ULONG MaxErrorCount;
|
|
|
|
ULONG Toggle;
|
|
|
|
LIST_ENTRY DoneTdList;
|
|
|
|
} ENDPOINT_DATA, *PENDPOINT_DATA;
|
|
|
|
#define UHCI_NUMBER_PORTS 2
|
|
|
|
#define UHCI_DDFLAG_USBBIOS 0x00000001
|
|
#define UHCI_DDFLAG_SUSPENDED 0x00000002
|
|
|
|
#define UHCI_HC_MAX_ERRORS 0x10
|
|
|
|
typedef struct _DEVICE_DATA {
|
|
|
|
ULONG Sig;
|
|
ULONG Flags;
|
|
PHC_REGISTER Registers;
|
|
ULONG HCErrorCount;
|
|
|
|
// Save the command register thru power downs
|
|
USBCMD SuspendCommandReg;
|
|
FRNUM SuspendFrameNumber;
|
|
FRBASEADD SuspendFrameListBasePhys;
|
|
USBINTR SuspendInterruptEnable;
|
|
|
|
USBINTR EnabledInterrupts;
|
|
ULONG IsoPendingTransfers;
|
|
|
|
//
|
|
// Base queue head that we link all control/bulk transfer
|
|
// queues to.
|
|
//
|
|
USB_CONTROLLER_FLAVOR ControllerFlavor;
|
|
|
|
// ULONG LastFrameCounter;
|
|
ULONG FrameNumberHighPart;
|
|
ULONG LastFrameProcessed;
|
|
ULONG SynchronizeIsoCleanup;
|
|
|
|
ULONG PortInReset;
|
|
ULONG PortResetChange;
|
|
ULONG PortSuspendChange;
|
|
ULONG PortOvercurrentChange;
|
|
BOOLEAN PortResuming[UHCI_NUMBER_PORTS];
|
|
|
|
USHORT IrqStatus;
|
|
|
|
USHORT PortPowerControl;
|
|
|
|
PHW_32BIT_PHYSICAL_ADDRESS FrameListVA;
|
|
HW_32BIT_PHYSICAL_ADDRESS FrameListPA;
|
|
|
|
// Virtual Addresses for the control and bulk queue heads in the
|
|
// schedule.
|
|
|
|
PHCD_QUEUEHEAD_DESCRIPTOR ControlQueueHead;
|
|
PHCD_QUEUEHEAD_DESCRIPTOR BulkQueueHead;
|
|
PHCD_QUEUEHEAD_DESCRIPTOR LastBulkQueueHead;
|
|
|
|
// Virtual Addresses for the interrupt queue heads in the
|
|
// schedule.
|
|
|
|
PHCD_QUEUEHEAD_DESCRIPTOR InterruptQueueHeads[NO_INTERRUPT_QH_LISTS];
|
|
|
|
// Virtual Address for the TD that gives us an interrupt at the end
|
|
// of every frame, so that things don't get stuck in the schedule.
|
|
|
|
PHCD_TRANSFER_DESCRIPTOR RollOverTd;
|
|
|
|
UCHAR SavedSOFModify;
|
|
|
|
PHCD_TD_LIST SofTdList;
|
|
|
|
} DEVICE_DATA, *PDEVICE_DATA;
|
|
|
|
|
|
/*
|
|
Callouts to port driver services
|
|
*/
|
|
extern USBPORT_REGISTRATION_PACKET RegistrationPacket;
|
|
|
|
#define USBPORT_DBGPRINT(dd, l, f, arg0, arg1, arg2, arg3, arg4, arg5) \
|
|
RegistrationPacket.USBPORTSVC_DbgPrint((dd), (l), (f), (arg0), (arg1), \
|
|
(arg2), (arg3), (arg4), (arg5))
|
|
|
|
#define USBPORT_GET_REGISTRY_KEY_VALUE(dd, branch, keystring, keylen, data, datalen) \
|
|
RegistrationPacket.USBPORTSVC_GetMiniportRegistryKeyValue((dd), (branch), \
|
|
(keystring), (keylen), (data), (datalen))
|
|
|
|
#define USBPORT_INVALIDATE_ROOTHUB(dd) \
|
|
RegistrationPacket.USBPORTSVC_InvalidateRootHub((dd))
|
|
|
|
#define USBPORT_COMPLETE_TRANSFER(dd, ep, tp, status, length) \
|
|
RegistrationPacket.USBPORTSVC_CompleteTransfer((dd), (ep), (tp), \
|
|
(status), (length))
|
|
|
|
#define USBPORT_COMPLETE_ISOCH_TRANSFER(dd, ep, tp, iso) \
|
|
RegistrationPacket.USBPORTSVC_CompleteIsoTransfer((dd), (ep), (tp), (iso))
|
|
|
|
#define USBPORT_INVALIDATE_ENDPOINT(dd, ep) \
|
|
RegistrationPacket.USBPORTSVC_InvalidateEndpoint((dd), (ep))
|
|
|
|
#define USBPORT_PHYSICAL_TO_VIRTUAL(addr, dd, ep) \
|
|
RegistrationPacket.USBPORTSVC_MapHwPhysicalToVirtual((addr), (dd), (ep))
|
|
|
|
#define USBPORT_REQUEST_ASYNC_CALLBACK(dd, t, c, cl, f) \
|
|
RegistrationPacket.USBPORTSVC_RequestAsyncCallback((dd), (t), \
|
|
(c), (cl), (f))
|
|
|
|
#define USBPORT_READ_CONFIG_SPACE(dd, b, o, l) \
|
|
RegistrationPacket.USBPORTSVC_ReadWriteConfigSpace((dd), TRUE, \
|
|
(b), (o), (l))
|
|
|
|
#define USBPORT_WRITE_CONFIG_SPACE(dd, b, o, l) \
|
|
RegistrationPacket.USBPORTSVC_ReadWriteConfigSpace((dd), FALSE, \
|
|
(b), (o), (l))
|
|
|
|
#define USBPORT_INVALIDATE_CONTROLLER(dd, s) \
|
|
RegistrationPacket.USBPORTSVC_InvalidateController((dd), (s))
|
|
|
|
#define USBPORT_WAIT(dd, t) \
|
|
RegistrationPacket.USBPORTSVC_Wait((dd), (t))
|
|
|
|
#define USBPORT_NOTIFY_DOUBLEBUFFER(dd, tp, addr, length) \
|
|
RegistrationPacket.USBPORTSVC_NotifyDoubleBuffer((dd), (tp), \
|
|
(addr), (length))
|
|
|
|
|
|
#ifdef _WIN64
|
|
#define DUMMY_TD_CONTEXT ((PVOID) 0xABADBABEABADBABE)
|
|
#else
|
|
#define DUMMY_TD_CONTEXT ((PVOID) 0xABADBABE)
|
|
#endif
|
|
|
|
|
|
#define UhciCheckIsochTransferInsertion(dd, r, df) {\
|
|
ULONG cf = UhciGet32BitFrameNumber((dd));\
|
|
if ((df) > (cf)) {\
|
|
if ((df) < (dd)->LastFrameProcessed + UHCI_MAX_FRAME) \
|
|
r = USBD_STATUS_SUCCESS;\
|
|
else\
|
|
r = USBD_STATUS_PENDING;\
|
|
} else {\
|
|
if ((df)-(cf) < UHCI_MAX_FRAME )\
|
|
r = USBD_STATUS_SUCCESS;\
|
|
else \
|
|
r = USBD_STATUS_BAD_START_FRAME;}}
|
|
|
|
//
|
|
// This macro is protected from double queueing the TD, by using
|
|
// interlocked function. Unless the HwAddress is NULL, it won't
|
|
// replace the value.
|
|
//
|
|
#define INSERT_ISOCH_TD(dd, td, fn) \
|
|
(td)->Flags |= TD_FLAG_ISO_QUEUED;\
|
|
InterlockedCompareExchange(&(td)->HwTD.LinkPointer.HwAddress,\
|
|
*( ((PULONG) ((dd)->FrameListVA)+ACTUAL_FRAME(fn)) ), 0);\
|
|
*( ((PULONG) ((dd)->FrameListVA)+ACTUAL_FRAME(fn)) ) = \
|
|
(td)->PhysicalAddress;
|
|
|
|
//
|
|
// Must account for both the regular and overflow cases:
|
|
//
|
|
/*#define CAN_INSERT_ISOCH_TD(fr, cfr) \
|
|
((fr - cfr < USBUHCI_MAX_FRAME) ||\
|
|
((fr + cfr < USBUHCI_MAX_FRAME) && fr < USBUHCI_MAX_FRAME))
|
|
|
|
#define INSERT_ISOCH_TD(dd, td, ep) \
|
|
(td)->PrevTd = (PHCD_TRANSFER_DESCRIPTOR)((PULONG) ((dd)->FrameListVA) + \
|
|
ACTUAL_FRAME((td)->IsoPacket->FrameNumber)); \
|
|
(td)->HwTD.LinkPointer.HwAddress = (td)->PrevTd->HwTD.LinkPointer.HwAddress; \
|
|
if (!(td)->HwTD.LinkPointer.QHTDSelect) {\
|
|
PHCD_TRANSFER_DESCRIPTOR rtd = (PHCD_TRANSFER_DESCRIPTOR)\
|
|
USBPORT_PHYSICAL_TO_VIRTUAL((td)->HwTD.LinkPointer.HwAddress, \
|
|
(dd), \
|
|
(ep));\
|
|
rtd->PrevTd = (td);\
|
|
}\
|
|
(td)->PrevTd->HwTD.LinkPointer.HwAddress = td->PhysicalAddress;
|
|
|
|
#define REMOVE_ISOCH_TD(td) \
|
|
(td)->PrevTd->HwTD.LinkPointer.HwAddress = (td)->HwTD.LinkPointer.HwAddress;
|
|
*/
|
|
|
|
// We must set the frame to the highest ULONG prior to setting the
|
|
// TD_FLAG_XFER flag, so that this TD doesn't get completed before
|
|
// we've had chance to queue it.
|
|
#define INITIALIZE_TD_FOR_TRANSFER(td, tc) \
|
|
(td)->TransferContext = (tc);\
|
|
(td)->Flags |= TD_FLAG_XFER; \
|
|
(td)->HwTD.LinkPointer.HwAddress = 0;\
|
|
(td)->HwTD.Control.ul = 0;\
|
|
(td)->HwTD.Control.LowSpeedDevice = ((tc)->EndpointData->Parameters.DeviceSpeed == LowSpeed);\
|
|
(td)->HwTD.Control.Active = 1;\
|
|
(td)->HwTD.Control.ErrorCount = 3;\
|
|
(td)->HwTD.Token.ul = 0;\
|
|
(td)->HwTD.Token.Endpoint = (tc)->EndpointData->Parameters.EndpointAddress;\
|
|
(td)->HwTD.Token.DeviceAddress = (tc)->EndpointData->Parameters.DeviceAddress;\
|
|
(td)->NextTd = NULL;
|
|
|
|
#define SET_QH_TD(dd, ed, td) {\
|
|
TD_LINK_POINTER newLink;\
|
|
if ((td)) {\
|
|
(ed)->HeadTd = (td);\
|
|
} else {\
|
|
(ed)->HeadTd = (ed)->TailTd = NULL;\
|
|
}\
|
|
if (!(td) || TEST_FLAG((ed)->Flags, UHCI_EDFLAG_HALTED)) {\
|
|
newLink.HwAddress = 0;\
|
|
newLink.Terminate = 1;\
|
|
} else {\
|
|
newLink.HwAddress = (td)->PhysicalAddress;\
|
|
newLink.Terminate = 0;\
|
|
}\
|
|
newLink.QHTDSelect = 0;\
|
|
LOGENTRY((dd), G, '_sqt', (td), (ed), 0);\
|
|
(ed)->QueueHead->HwQH.VLink = newLink;}
|
|
|
|
/*#define SET_QH_TD_NULL(qh) \
|
|
{ TD_LINK_POINTER newLink;\
|
|
newLink.HwAddress = 0;\
|
|
newLink.Terminate = 1;\
|
|
newLink.QHTDSelect = 0;\
|
|
(qh)->HwQH.VLink = newLink;\
|
|
}
|
|
*/
|
|
#define SET_NEXT_TD(linkTd, nextTd) \
|
|
(linkTd)->HwTD.LinkPointer.HwAddress = (nextTd)->PhysicalAddress;\
|
|
(linkTd)->HwTD.LinkPointer.Terminate = 0;\
|
|
(linkTd)->HwTD.LinkPointer.QHTDSelect = 0;\
|
|
(linkTd)->HwTD.LinkPointer.DepthBreadthSelect = 0;\
|
|
(linkTd)->NextTd = (nextTd);
|
|
|
|
#define SET_NEXT_TD_NULL(linkTd) \
|
|
(linkTd)->NextTd = NULL;\
|
|
(linkTd)->HwTD.LinkPointer.HwAddress = 0;\
|
|
(linkTd)->HwTD.LinkPointer.Terminate = 1;
|
|
|
|
#define PAGE_CROSSING(PhysicalAddress, length) \
|
|
((PhysicalAddress+length)%PAGE_SIZE < length && (PhysicalAddress+length)%PAGE_SIZE != 0)
|
|
|
|
#ifdef _WIN64
|
|
#define UHCI_BAD_POINTER ((PVOID) 0xDEADFACEDEADFACE)
|
|
#else
|
|
#define UHCI_BAD_POINTER ((PVOID) 0xDEADFACE)
|
|
#endif
|
|
#define UHCI_BAD_HW_POINTER 0x0BADF00D
|
|
|
|
// Note how we free any double buffering in here instead of relying
|
|
// on the c code to do it.
|
|
#define UHCI_FREE_TD(dd, ep, td) \
|
|
if (TEST_FLAG((td)->Flags, TD_FLAG_DOUBLE_BUFFERED)) { \
|
|
UHCI_FREE_DB((dd), (ep), (td)->DoubleBuffer);}\
|
|
(ep)->TdsUsed--;\
|
|
(td)->HwTD.LinkPointer.HwAddress = UHCI_BAD_HW_POINTER;\
|
|
LOGENTRY((dd), G, '_fTD', (td), (ep), 0);\
|
|
(td)->TransferContext = UHCI_BAD_POINTER;\
|
|
(td)->Flags = 0;
|
|
|
|
#define UHCI_ALLOC_TD(dd, ep) UhciAllocTd((dd), (ep));
|
|
|
|
#define UHCI_FREE_DB(dd, ep, db) \
|
|
LOGENTRY((dd), G, '_fDB', (db), (ep), 0);\
|
|
(ep)->DbsUsed--;\
|
|
if ((ep)->Parameters.TransferType == Isochronous) { (db)->Isoch.Flags = 0; }\
|
|
else { (db)->Async.Flags = 0; }
|
|
|
|
#define UHCI_ALLOC_DB(dd, ep, i) UhciAllocDb((dd), (ep), (i));
|
|
|
|
// bugbug UHCI_ASSERT((dd), (ed)->PendingTransfers);
|
|
#define DecPendingTransfers(dd, ed) \
|
|
InterlockedDecrement(&(ed)->PendingTransfers);\
|
|
if ((ed)->Parameters.TransferType == Isochronous)\
|
|
InterlockedDecrement(&(dd)->IsoPendingTransfers);
|
|
|
|
#define ActivateRolloverTd(dd) \
|
|
*( ((PULONG) ((dd)->FrameListVA)) ) = (dd)->RollOverTd->PhysicalAddress;
|
|
|
|
//#define IncPendingTransfers(dd, ed) \
|
|
// InterlockedIncrement(&(ed)->PendingTransfers);\
|
|
// if ((ed)->Parameters.TransferType == Isochronous) {\
|
|
// if (1 == InterlockedIncrement(&(dd)->IsoPendingTransfers)) {\
|
|
// //*( ((PULONG) ((dd)->FrameListVA)) ) = (dd)->RollOverTd->PhysicalAddress; \
|
|
// (dd)->LastFrameProcessed = UhciGet32BitFrameNumber((dd));\
|
|
// }}
|
|
// bugbug UHCI_ASSERT((dd), (ed)->PendingTransfers);
|
|
|
|
#define IncPendingTransfers(dd, ed) \
|
|
InterlockedIncrement(&(ed)->PendingTransfers);\
|
|
if ((ed)->Parameters.TransferType == Isochronous) {\
|
|
if (1 == InterlockedIncrement(&(dd)->IsoPendingTransfers)) {\
|
|
(dd)->LastFrameProcessed = UhciGet32BitFrameNumber((dd));\
|
|
}}
|
|
// bugbug UHCI_ASSERT((dd), (ed)->PendingTransfers);
|
|
|
|
|
|
#define UhciCleanFrameOfIsochTds(dd, i)\
|
|
if ((i) == 0) {\
|
|
*( ((PULONG) ((dd)->FrameListVA)) ) = (dd)->RollOverTd->PhysicalAddress;\
|
|
} else {\
|
|
QH_LINK_POINTER newLink;\
|
|
newLink.HwAddress = (dd)->InterruptQueueHeads[QH_INTERRUPT_32ms + MAX_INTERVAL_MASK((i))]->PhysicalAddress;\
|
|
newLink.QHTDSelect = 1;\
|
|
*( ((PULONG) ((dd)->FrameListVA)+(i)) ) = newLink.HwAddress;\
|
|
}
|
|
|
|
|
|
#define TEST_BIT(value, bitNumber) ((value) & (1<<(bitNumber))) ? TRUE : FALSE
|
|
|
|
#define SET_BIT(value, bitNumber) ((value) |= (1<<(bitNumber)))
|
|
|
|
#define CLEAR_BIT(value, bitNumber) ((value) &= ~(1<<(bitNumber)))
|
|
|
|
|
|
//
|
|
// Controller functions
|
|
//
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciStartController(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PHC_RESOURCES HcResources
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciStopController(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN BOOLEAN HwPresent
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciSuspendController(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciResumeController(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciPollController(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
ULONG
|
|
USBMPFN
|
|
UhciGet32BitFrameNumber(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciInterruptNextSOF(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
UhciUpdateCounter(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
UhciDisableAsyncList(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
UhciInitailizeInterruptSchedule(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
UhciEnableAsyncList(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciPassThru (
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN GUID *FunctionGuid,
|
|
IN ULONG ParameterLength,
|
|
IN OUT PVOID Parameters
|
|
);
|
|
|
|
|
|
//
|
|
// Root hub functions
|
|
//
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciRHGetRootHubData(
|
|
IN PDEVICE_DATA DeviceData,
|
|
OUT PROOTHUB_DATA HubData
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHGetStatus(
|
|
IN PDEVICE_DATA DeviceData,
|
|
OUT PUSHORT Status
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHGetHubStatus(
|
|
IN PDEVICE_DATA DeviceData,
|
|
OUT PRH_HUB_STATUS HubStatus
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciRHDisableIrq(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciRHEnableIrq(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
|
|
//
|
|
// Root hub port functions
|
|
//
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHSetFeaturePortReset(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHSetFeaturePortSuspend(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHClearFeaturePortSuspend(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHSetFeaturePortPower(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHClearFeaturePortPower(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHSetFeaturePortEnable(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHClearFeaturePortEnable(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHGetPortStatus(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber,
|
|
PRH_PORT_STATUS portStatus
|
|
);
|
|
|
|
//
|
|
// Clear change bits for hub ports
|
|
//
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHClearFeaturePortConnectChange(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHClearFeaturePortResetChange(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHClearFeaturePortSuspendChange(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHClearFeaturePortOvercurrentChange(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciRHClearFeaturePortEnableChange(
|
|
PDEVICE_DATA DeviceData,
|
|
USHORT PortNumber
|
|
);
|
|
|
|
|
|
//
|
|
// Interrupt functions
|
|
//
|
|
|
|
BOOLEAN
|
|
USBMPFN
|
|
UhciInterruptService (
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciEnableInterrupts(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciInterruptDpc (
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN BOOLEAN EnableInterrupts
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciDisableInterrupts(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
|
|
//
|
|
// Endpoint functions
|
|
//
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciOpenEndpoint(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_PARAMETERS EndpointParameters,
|
|
OUT PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciPokeEndpoint(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_PARAMETERS EndpointParameters,
|
|
OUT PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciQueryEndpointRequirements(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_PARAMETERS EndpointParameters,
|
|
OUT PENDPOINT_REQUIREMENTS EndpointRequirements
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciCloseEndpoint(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciAbortTransfer(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN PTRANSFER_CONTEXT TransferContext,
|
|
OUT PULONG BytesTransferred
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciStartSendOnePacket(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PMP_PACKET_PARAMETERS PacketParameters,
|
|
IN PUCHAR PacketData,
|
|
IN PULONG PacketLength,
|
|
IN PUCHAR WorkspaceVirtualAddress,
|
|
IN HW_32BIT_PHYSICAL_ADDRESS WorkspacePhysicalAddress,
|
|
IN ULONG WorkSpaceLength,
|
|
IN OUT USBD_STATUS *UsbdStatus
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciEndSendOnePacket(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PMP_PACKET_PARAMETERS PacketParameters,
|
|
IN PUCHAR PacketData,
|
|
IN PULONG PacketLength,
|
|
IN PUCHAR WorkspaceVirtualAddress,
|
|
IN HW_32BIT_PHYSICAL_ADDRESS WorkspacePhysicalAddress,
|
|
IN ULONG WorkSpaceLength,
|
|
IN OUT USBD_STATUS *UsbdStatus
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciSetEndpointStatus(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN MP_ENDPOINT_STATUS Status
|
|
);
|
|
|
|
MP_ENDPOINT_STATUS
|
|
USBMPFN
|
|
UhciGetEndpointStatus(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
PHCD_QUEUEHEAD_DESCRIPTOR
|
|
UhciInitializeQH(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN PHCD_QUEUEHEAD_DESCRIPTOR Qh,
|
|
IN HW_32BIT_PHYSICAL_ADDRESS HwPhysAddress
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciSetEndpointDataToggle(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN ULONG Toggle
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciPollEndpoint(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
MP_ENDPOINT_STATE
|
|
USBMPFN
|
|
UhciGetEndpointState(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
VOID
|
|
USBMPFN
|
|
UhciSetEndpointState(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN MP_ENDPOINT_STATE State
|
|
);
|
|
|
|
VOID
|
|
UhciSetAsyncEndpointState(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN MP_ENDPOINT_STATE State
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciSubmitTransfer(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN PTRANSFER_PARAMETERS TransferUrb,
|
|
IN PTRANSFER_CONTEXT TransferContext,
|
|
IN PTRANSFER_SG_LIST TransferSGList
|
|
);
|
|
|
|
//
|
|
// Async
|
|
//
|
|
|
|
VOID
|
|
UhciProcessDoneAsyncTd(
|
|
PDEVICE_DATA DeviceData,
|
|
PHCD_TRANSFER_DESCRIPTOR Td
|
|
);
|
|
|
|
VOID
|
|
UhciPollAsyncEndpoint(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
UhciBulkOrInterruptTransfer(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN PTRANSFER_PARAMETERS TransferParameters,
|
|
IN PTRANSFER_CONTEXT TransferContext,
|
|
IN PTRANSFER_SG_LIST TransferSGList
|
|
);
|
|
|
|
VOID
|
|
UhciUnlinkQh(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PHCD_QUEUEHEAD_DESCRIPTOR Qh
|
|
);
|
|
|
|
VOID
|
|
UhciAbortAsyncTransfer(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN PTRANSFER_CONTEXT TransferContext,
|
|
OUT PULONG BytesTransferred
|
|
);
|
|
|
|
VOID
|
|
UhciInsertQh(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PHCD_QUEUEHEAD_DESCRIPTOR FirstQh,
|
|
IN PHCD_QUEUEHEAD_DESCRIPTOR LinkQh
|
|
);
|
|
|
|
USB_MINIPORT_STATUS
|
|
UhciControlTransfer(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN PTRANSFER_PARAMETERS TransferUrb,
|
|
IN PTRANSFER_CONTEXT TransferContext,
|
|
IN PTRANSFER_SG_LIST TransferSGList
|
|
);
|
|
|
|
//
|
|
// Isoch
|
|
//
|
|
|
|
USB_MINIPORT_STATUS
|
|
USBMPFN
|
|
UhciIsochTransfer(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN PTRANSFER_PARAMETERS TransferParameters,
|
|
IN PTRANSFER_CONTEXT TransferContext,
|
|
IN PMINIPORT_ISO_TRANSFER IsoTransfer
|
|
);
|
|
|
|
VOID
|
|
UhciPollIsochEndpoint(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
VOID
|
|
UhciAbortIsochTransfer(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN PTRANSFER_CONTEXT TransferContext
|
|
);
|
|
|
|
VOID
|
|
UhciSetIsochEndpointState(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN MP_ENDPOINT_STATE State
|
|
);
|
|
|
|
VOID
|
|
UhciCleanOutIsoch(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN BOOLEAN ForceClean
|
|
);
|
|
|
|
//
|
|
// Utility
|
|
//
|
|
|
|
USBD_STATUS
|
|
UhciGetErrorFromTD(
|
|
PDEVICE_DATA DeviceData,
|
|
PHCD_TRANSFER_DESCRIPTOR Td
|
|
);
|
|
|
|
PHCD_TRANSFER_DESCRIPTOR
|
|
UhciAllocTd(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData
|
|
);
|
|
|
|
PTRANSFER_BUFFER
|
|
UhciAllocDb(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_DATA EndpointData,
|
|
IN BOOLEAN Isoch
|
|
);
|
|
|
|
//
|
|
// Bios handoff and handback
|
|
//
|
|
USB_MINIPORT_STATUS
|
|
UhciStopBIOS(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PHC_RESOURCES HcResources
|
|
);
|
|
|
|
ULONG
|
|
UhciQueryControlRequirements(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_PARAMETERS EndpointParameters,
|
|
IN OUT PULONG NumberOfTDs,
|
|
IN OUT PULONG NumberOfDoubleBuffers
|
|
);
|
|
|
|
ULONG
|
|
UhciQueryBulkRequirements(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_PARAMETERS EndpointParameters,
|
|
IN OUT PULONG NumberOfTDs,
|
|
IN OUT PULONG NumberOfDoubleBuffers
|
|
);
|
|
|
|
ULONG
|
|
UhciQueryIsoRequirements(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_PARAMETERS EndpointParameters,
|
|
IN OUT PULONG NumberOfTDs,
|
|
IN OUT PULONG NumberOfDoubleBuffers
|
|
);
|
|
|
|
ULONG
|
|
UhciQueryInterruptRequirements(
|
|
IN PDEVICE_DATA DeviceData,
|
|
IN PENDPOINT_PARAMETERS EndpointParameters,
|
|
IN OUT PULONG NumberOfTDs,
|
|
IN OUT PULONG NumberOfDoubleBuffers
|
|
);
|
|
|
|
BOOLEAN
|
|
UhciHardwarePresent(
|
|
PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
UhciCheckController(
|
|
PDEVICE_DATA DeviceData
|
|
);
|
|
|
|
VOID
|
|
UhciFlushInterrupts(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
/*
|
|
USB_MINIPORT_STATUS
|
|
UhciStartBIOS(
|
|
IN PDEVICE_DATA DeviceData
|
|
);
|
|
*/
|
|
|
|
#endif /* __USBUHCI_H__ */
|
|
|
|
|