td.h
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C头文件 代码 · 共 1,050 行 · 第 1/2 页
H
1,050 行
#define USB_DEV_STATE_POWERED ( 0x01 << 8 )
#define USB_DEV_STATE_RESET ( 0x02 << 8 )
#define USB_DEV_STATE_ADDRESSED ( 0x03 << 8 )
#define USB_DEV_STATE_FIRST_CONFIG ( 0x04 << 8 )
#define USB_DEV_STATE_RECONFIG ( 0x05 << 8 )
#define USB_DEV_STATE_CONFIGURED ( 0x06 << 8 )
#define USB_DEV_STATE_SUSPENDED ( 0x07 << 8 )
#define USB_DEV_STATE_BEFORE_ZOMB ( 0x08 << 8 )
#define USB_DEV_STATE_ZOMB ( 0x09 << 8 )
#define USB_DEV_CLASS_MASK ( 0xff << 16 )
#define USB_DEV_CLASS_HUB ( USB_CLASS_HUB << 16 )
#define USB_DEV_CLASS_MASSSTOR ( USB_CLASS_MASS_STORAGE << 16 )
#define USB_DEV_CLASS_ROOT_HUB ( ( USB_CLASS_VENDOR_SPEC - 2 ) << 16 )
#define USB_DEV_CLASS_SCANNER ( ( USB_DEV_CLASS_ROOT_HUB - 1 ) << 16 )
#define USB_DEV_FLAG_HIGH_SPEED 0x20 // high speed dev for usb2.0
#define USB_DEV_FLAG_LOW_SPEED 0x40 // note: this bit is shared in urb->pipe
#define USB_DEV_FLAG_IF_DEV 0x01 // this dev is a virtual dev, that is a interface
#define lock_dev( pdev, at_dpc ) \
{\
KIRQL cur_irql;\
cur_irql = KeGetCurrentIrql();\
if( cur_irql == DISPATCH_LEVEL )\
{\
KeAcquireSpinLockAtDpcLevel( &pdev->dev_lock );\
_dev_lock_old_irql = DISPATCH_LEVEL;\
}\
else if( cur_irql < DISPATCH_LEVEL )\
KeAcquireSpinLock( &pdev->dev_lock, &_dev_lock_old_irql );\
else\
TRAP();\
}
#define unlock_dev( pdev, from_dpc ) \
{\
if( _dev_lock_old_irql == DISPATCH_LEVEL )\
KeReleaseSpinLockFromDpcLevel( &pdev->dev_lock );\
else if( _dev_lock_old_irql < DISPATCH_LEVEL )\
KeReleaseSpinLock( &pdev->dev_lock, _dev_lock_old_irql );\
else\
TRAP();\
}
typedef struct _USB_DEV
{
LIST_ENTRY dev_link; //for dev-list
KSPIN_LOCK dev_lock;
PDEVICE_OBJECT dev_obj;
ULONG flags; //class | cur_state | low speed
LONG ref_count; //client count
UCHAR dev_addr; //usb addr
ULONG dev_id; //will be used to compose dev handle
struct _USB_DEV *parent_dev;
UCHAR port_idx; //parent hub's port idx, to which the dev attached
struct _HCD *hcd; //point to the hcd the dev belongs to
USB_ENDPOINT default_endp; //control endp. its interfac pointer is to the first interface
LONG desc_buf_size;
PUCHAR desc_buf;
struct _USB_DEVICE_DESC *pusb_dev_desc;
UCHAR active_config_idx;
PUSB_CONFIGURATION usb_config; //the active configuration
struct _USB_DRIVER *dev_driver;
PVOID dev_ext;
LONG dev_ext_size;
LONG time_out_count; //default pipe error counter, three time-outs will cause the dev not function
LONG error_count; //usb transfer error counter for statics only
} USB_DEV, *PUSB_DEV;
// pending endpoint pool definitions
#define UHCI_MAX_PENDING_ENDPS 32
typedef struct _UHCI_PENDING_ENDP
{
LIST_ENTRY endp_link;
PUSB_ENDPOINT pendp;
} UHCI_PENDING_ENDP, *PUHCI_PENDING_ENDP;
typedef struct _UHCI_PENDING_ENDP_POOL
{
PUHCI_PENDING_ENDP pending_endp_array;
LIST_ENTRY free_que;
LONG free_count;
LONG total_count;
KSPIN_LOCK pool_lock;
} UHCI_PENDING_ENDP_POOL, *PUHCI_PENDING_ENDP_POOL;
BOOLEAN
init_pending_endp_pool(
PUHCI_PENDING_ENDP_POOL pool
);
BOOLEAN
free_pending_endp(
PUHCI_PENDING_ENDP_POOL pool,
PUHCI_PENDING_ENDP pending_endp
);
PUHCI_PENDING_ENDP
alloc_pending_endp(
PUHCI_PENDING_ENDP_POOL pool,
LONG count
);
BOOLEAN
destroy_pending_endp_pool(
PUHCI_PENDING_ENDP_POOL pool
);
// pool type is PUHCI_PENDING_ENDP_POOL
#define lock_pending_endp_pool( pool ) \
{\
KeAcquireSpinLock( &pool->pool_lock, &_pending_endp_lock_old_irql );\
}
#define unlock_pending_endp_pool( pool ) \
{\
KeReleaseSpinLock( &pool->pool_lock, &_pending_endp_lock_old_irql );\
}
// end of pending endpoint pool
typedef struct _FRAME_LIST_CPU_ENTRY
{
LIST_ENTRY td_link;
} FRAME_LIST_CPU_ENTRY, *PFRAME_LIST_CPU_ENTRY;
#define uhci_public_res_lock pending_endp_list_lock
#define uhci_status( _uhci_ ) ( READ_PORT_USHORT( ( PUSHORT )( ( _uhci_ )->port_base + USBSTS ) ) )
typedef struct _UHCI
{
PHYSICAL_ADDRESS uhci_reg_base; // io space
BOOLEAN port_mapped;
PBYTE port_base;
PHYSICAL_ADDRESS io_buf_logic_addr;
PBYTE io_buf;
PHYSICAL_ADDRESS frame_list_logic_addr;
KSPIN_LOCK frame_list_lock; //run at DIRQL
PULONG frame_list;
PFRAME_LIST_CPU_ENTRY frame_list_cpu;
LIST_HEAD urb_list; //active urb-list
PUHCI_TD skel_td[UHCI_MAX_SKELTDS];
PUHCI_QH skel_qh[UHCI_MAX_SKELQHS]; //skeltons
UHCI_TD_POOL_LIST td_pool;
UHCI_QH_POOL qh_pool;
//for iso and int bandwidth claim, bandwidth schedule
KSPIN_LOCK pending_endp_list_lock; //lock to access the following two
LIST_HEAD pending_endp_list;
UHCI_PENDING_ENDP_POOL pending_endp_pool;
PLONG frame_bw;
LONG fsbr_cnt; //used to record number of fsbr users
KTIMER reset_timer; //used to reset the host controller
//struct _USB_DEV_MANAGER dev_mgr; //it is in hcd_interf
struct _DEVICE_EXTENSION *pdev_ext;
PUSB_DEV root_hub; //root hub
HCD hcd_interf;
} UHCI_DEV, *PUHCI_DEV;
#define lock_pending_endp_list( list_lock ) \
{\
KeAcquireSpinLock( list_lock, &_pending_endp_list_lock_old_irql );\
}
#define unlock_pending_endp_list( list_lock ) \
{\
KeReleaseSpinLock( list_lock, _pending_endp_list_lock_old_irql );\
}
typedef struct _UHCI_INTERRUPT
{
ULONG level;
ULONG vector;
ULONG affinity;
} UHCI_INTERRUPT, *PUHCI_INTERRUPT;
typedef struct _UHCI_PORT
{
PHYSICAL_ADDRESS Start;
ULONG Length;
} UHCI_PORT, *PUHCI_PORT;
typedef NTSTATUS ( *PDISPATCH_ROUTINE )( PDEVICE_OBJECT dev_obj, PIRP irp );
#define NTDEV_TYPE_HCD 1
#define NTDEV_TYPE_CLIENT_DEV 2
typedef struct _DEVEXT_HEADER
{
ULONG type;
PDISPATCH_ROUTINE dispatch;
PDRIVER_STARTIO start_io;
struct _USB_DEV_MANAGER *dev_mgr; //mainly for use by cancel irp
} DEVEXT_HEADER, *PDEVEXT_HEADER;
typedef struct _DEVICE_EXTENSION
{
//struct _USB_DEV_MANAGER *pdev_mgr;
DEVEXT_HEADER dev_ext_hdr;
PDEVICE_OBJECT pdev_obj;
PDRIVER_OBJECT pdrvr_obj;
PUHCI_DEV uhci;
//device resources
PADAPTER_OBJECT padapter;
ULONG map_regs;
PCM_RESOURCE_LIST res_list;
ULONG pci_addr; // bus number | slot number | funciton number
UHCI_INTERRUPT res_interrupt;
UHCI_PORT res_port;
PKINTERRUPT uhci_int;
KDPC uhci_dpc;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
//helper macro
#define ListFirst( heAD, firST) \
{\
if( IsListEmpty( ( heAD ) ) )\
firST = NULL;\
else\
firST = ( heAD )->Flink;\
}
#define ListNext( heAD, curreNT, neXT) \
{\
if( IsListEmpty( ( heAD ) ) == FALSE )\
{\
neXT = (curreNT)->Flink;\
if( neXT == heAD )\
neXT = NULL;\
}\
else\
neXT = NULL;\
}
#define ListPrev( heAD, curreNT, prEV) \
{\
if( IsListEmpty( ( heAD ) ) == FALSE )\
{\
prEV = (curreNT)->Blink;\
if( prEV == heAD )\
prEV = NULL;\
else\
prEV = NULL;\
}
#define ListFirstPrev( heAD, firST) \
{\
if( IsListEmpty( ( heAD ) ) )\
firST = NULL;\
else\
firST = ( heAD )->Blink;\
}
#define MergeList( liST1, liST2 )\
{\
PLIST_ENTRY taIL1, taIL2;\
if( IsListEmpty( liST2 ) == TRUE )\
{\
InsertTailList( liST1, liST2 );\
}\
else if( IsListEmpty( liST1 ) == TRUE )\
{\
InsertTailList( liST2, liST1 );\
}\
else\
{\
ListFirstPrev( liST1, taIL1 );\
ListFirstPrev( liST2, taIL2 );\
\
taIL1->Flink = ( liST2 );\
( liST2 )->Blink = taIL1;\
\
taIL2->Flink = ( liST1 );\
( liST1 )->Blink = taIL2;\
}\
}
PUHCI_TD
alloc_tds(
PUHCI_TD_POOL_LIST pool_list,
LONG count
);
VOID
free_tds(
PUHCI_TD_POOL_LIST pool_list,
PUHCI_TD ptd
);
BOOLEAN
uhci_init(
PUHCI_DEV uhci,
PADAPTER_OBJECT padapter
);
BOOLEAN
uhci_destroy(
PUHCI_DEV uhci
);
// funcitons exported to dev-manager
BOOLEAN
uhci_add_device(
PUHCI_DEV uhci,
PUSB_DEV dev
);
BOOLEAN
uhci_remove_device(
PUHCI_DEV uhci,
PUSB_DEV dev
);
//helpers
VOID NTAPI
uhci_dpc_callback(
PKDPC dpc,
PVOID context,
PVOID sysarg1,
PVOID sysarg2
);
#if 0
static VOID
uhci_flush_adapter_buf()
{
#ifdef _X86
__asm invd;
#endif
}
#endif
NTSTATUS
uhci_submit_urb(
PUHCI_DEV uhci,
PUSB_DEV pdev,
PUSB_ENDPOINT pendp,
struct _URB *urb
);
//must have dev_lock acquired
NTSTATUS
uhci_internal_submit_bulk(
PUHCI_DEV uhci,
struct _URB *urb
);
NTSTATUS
uhci_internal_submit_iso(
PUHCI_DEV uhci,
struct _URB *urb
);
NTSTATUS
uhci_internal_submit_ctrl(
PUHCI_DEV uhci,
struct _URB *urb
);
NTSTATUS
uhci_internal_submit_int(
PUHCI_DEV uhci,
struct _URB *urb
);
BOOLEAN
uhci_remove_bulk_from_schedule(
PUHCI_DEV uhci,
struct _URB *urb
);
#define uhci_remove_ctrl_from_schedule uhci_remove_bulk_from_schedule
BOOLEAN
uhci_remove_iso_from_schedule(
PUHCI_DEV uhci,
struct _URB *urb
);
BOOLEAN
uhci_remove_int_from_schedule(
PUHCI_DEV uhci,
struct _URB *urb
);
BOOLEAN
uhci_remove_urb_from_schedule(
PUHCI_DEV uhci,
struct _URB *urb
);
BOOLEAN
uhci_is_xfer_finished( //will set urb error code here
struct _URB *urb
);
NTSTATUS
uhci_set_error_code(
struct _URB *urb,
ULONG raw_status
);
BOOLEAN
uhci_insert_tds_qh(
PUHCI_QH pqh,
PUHCI_TD td_chain
);
BOOLEAN
uhci_insert_qh_urb(
struct _URB *urb,
PUHCI_QH qh_chain
);
BOOLEAN
uhci_insert_urb_schedule(
PUHCI_DEV uhci,
struct _URB *urb
);
BOOLEAN
uhci_claim_bandwidth(
PUHCI_DEV uhci,
struct _URB *urb,
BOOLEAN claim_bw
);
BOOLEAN
uhci_process_pending_endp(
PUHCI_DEV uhci
);
NTSTATUS
uhci_cancel_urb(
PUHCI_DEV uhci,
PUSB_DEV pdev,
PUSB_ENDPOINT endp,
struct _URB *urb
);
VOID
uhci_generic_urb_completion(
struct _URB *urb,
PVOID context
);
// the following are NT driver definitions
// NT device name
#define UHCI_DEVICE_NAME "\\Device\\UHCI"
// File system device name. When you execute a CreateFile call to open the
// device, use "\\.\GpdDev", or, given C's conversion of \\ to \, use
// "\\\\.\\GpdDev"
#define DOS_DEVICE_NAME "\\DosDevices\\UHCI"
#define CLR_RH_PORTSTAT( port_idx, x ) \
{\
PUSHORT addr; \
addr = ( PUSHORT )( uhci->port_base + port_idx ); \
status = READ_PORT_USHORT( addr ); \
status = ( status & 0xfff5 ) & ~( x ); \
WRITE_PORT_USHORT( addr, ( USHORT )status ); \
}
#define SET_RH_PORTSTAT( port_idx, x ) \
{\
PUSHORT addr; \
addr = ( PUSHORT )( uhci->port_base + port_idx ); \
status = READ_PORT_USHORT( addr ); \
status = ( status & 0xfff5 ) | ( x ); \
WRITE_PORT_USHORT( addr, ( USHORT )status ); \
}
//this is for dispatch routine
#define EXIT_DISPATCH( nTstatUs, iRp)\
{\
if( nTstatUs != STATUS_PENDING)\
{\
iRp->IoStatus.Status = nTstatUs;\
IoCompleteRequest( iRp, IO_NO_INCREMENT);\
return nTstatUs;\
}\
IoMarkIrpPending( iRp);\
return nTstatUs;\
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?