2 * NOTE!!!: part of the code is pasted from linux/driver/usb/uhci.h
8 #define LIST_HEAD LIST_ENTRY
9 #define PLIST_HEAD PLIST_ENTRY
16 #define LOWORD(l) ( (WORD) ( ( l ) & 0xffff ) )
19 #define HIWORD(l) ( (WORD) ( ( l ) >> 16 ) )
22 #define PCI_MAX_FUNCTIONS 8
25 #define UHCI_MAX_POOL_TDS 1024 //8 pages of 4k
26 #define UHCI_MAX_POOL_QHS 256 //1 page of 4k
27 #define UHCI_MAX_ANT_TDS 0x20e82
29 #define UHCI_MAX_TD_POOLS 8
30 #define UHCI_MAX_TDS_PER_TRANSFER UHCI_MAX_POOL_TDS
32 #define UHCI_FULL_SPEED_BANDWIDHT ( 12 * 1000 * 1000 )
33 #define UHCI_LOW_SPEED_BANDWIDHT ( 15 * 100 * 1000 )
35 * Universal Host Controller Interface data structures and defines
38 /* Command register */
40 #define USBCMD_RS 0x0001 /* Run/Stop */
41 #define USBCMD_HCRESET 0x0002 /* Host reset */
42 #define USBCMD_GRESET 0x0004 /* Global reset */
43 #define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
44 #define USBCMD_FGR 0x0010 /* Force Global Resume */
45 #define USBCMD_SWDBG 0x0020 /* SW Debug mode */
46 #define USBCMD_CF 0x0040 /* Config Flag (sw only) */
47 #define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
51 #define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
52 #define USBSTS_ERROR 0x0002 /* Interrupt due to error */
53 #define USBSTS_RD 0x0004 /* Resume Detect */
54 #define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */
55 #define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */
56 #define USBSTS_HCH 0x0020 /* HC Halted */
58 /* Interrupt enable register */
60 #define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */
61 #define USBINTR_RESUME 0x0002 /* Resume interrupt enable */
62 #define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */
63 #define USBINTR_SP 0x0008 /* Short packet interrupt enable */
66 #define USBFLBASEADD 8
69 /* USB port status and control registers */
72 #define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */
73 #define USBPORTSC_CSC 0x0002 /* Connect Status Change */
74 #define USBPORTSC_PE 0x0004 /* Port Enable */
75 #define USBPORTSC_PEC 0x0008 /* Port Enable Change */
76 #define USBPORTSC_LS 0x0020 /* Line Status */
77 #define USBPORTSC_RD 0x0040 /* Resume Detect */
78 #define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */
79 #define USBPORTSC_PR 0x0200 /* Port Reset */
80 #define USBPORTSC_SUSP 0x1000 /* Suspend */
82 /* Legacy support register */
83 #define USBLEGSUP 0xc0
84 #define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
85 #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
86 #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
89 #define UHCI_NULL_DATA_SIZE 0x7FF /* for UHCI controller TD */
91 #define UHCI_PTR_BITS 0x000F
92 #define UHCI_PTR_TERM 0x0001
93 #define UHCI_PTR_QH 0x0002
94 #define UHCI_PTR_DEPTH 0x0004
96 #define UHCI_MAX_FRAMES 1024 /* in the frame list [array] */
97 #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
98 #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */
101 //from linux's uhci.h
102 #define UHCI_MAX_SKELTDS 10
103 #define skel_int1_td skel_td[0]
104 #define skel_int2_td skel_td[1]
105 #define skel_int4_td skel_td[2]
106 #define skel_int8_td skel_td[3]
107 #define skel_int16_td skel_td[4]
108 #define skel_int32_td skel_td[5]
109 #define skel_int64_td skel_td[6]
110 #define skel_int128_td skel_td[7]
111 #define skel_int256_td skel_td[8]
112 #define skel_term_td skel_td[9] /* To work around PIIX UHCI bug */
114 #define UHCI_MAX_SKELQHS 4
115 #define skel_ls_control_qh skel_qh[0]
116 #define skel_hs_control_qh skel_qh[1]
117 #define skel_bulk_qh skel_qh[2]
118 #define skel_term_qh skel_qh[3]
127 #define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
128 #define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
129 #define TD_CTRL_C_ERR_SHIFT 27
130 #define TD_CTRL_LS (1 << 26) /* Low Speed Device */
131 #define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
132 #define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
133 #define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
134 #define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
135 #define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
136 #define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
137 #define TD_CTRL_NAK (1 << 19) /* NAK Received */
138 #define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
139 #define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
140 #define TD_CTRL_ACTLEN_MASK 0x7FF /* actual length, encoded as n - 1 */
142 #define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
143 TD_CTRL_BABBLE | TD_CTRL_CRCTIMEO | TD_CTRL_BITSTUFF)
145 #define uhci_status_bits(ctrl_sts) (ctrl_sts & 0xFE0000)
146 #define uhci_actual_length(ctrl_sts) ((ctrl_sts + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
149 * for TD <info>: (a.k.a. Token)
151 #define TD_TOKEN_TOGGLE 19
154 #define uhci_maxlen(token) ((token) >> 21)
155 #define uhci_expected_length(info) (((info >> 21) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
156 #define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE) & 1)
157 #define uhci_endpoint(token) (((token) >> 15) & 0xf)
158 #define uhci_devaddr(token) (((token) >> 8) & 0x7f)
159 #define uhci_devep(token) (((token) >> 8) & 0x7ff)
160 #define uhci_packetid(token) ((token) & 0xff)
161 #define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN)
162 #define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN)
165 * The documentation says "4 dwords for hardware, 4 dwords for software".
167 * That's silly, the hardware doesn't care. The hardware only cares that
168 * the hardware words are 16-byte aligned, and we can have any amount of
169 * sw space after the TD entry as far as I can tell.
171 * But let's just go with the documentation, at least for 32-bit machines.
172 * On 64-bit machines we probably want to take advantage of the fact that
173 * hw doesn't really care about the size of the sw-only area.
175 * Alas, not anymore, we have more than 4 dwords for software, woops.
176 * Everything still works tho, surprise! -jerdfelt
179 #define UHCI_ITEM_FLAG_TYPE 0x3
180 #define UHCI_ITEM_FLAG_TD 0x0
181 #define UHCI_ITEM_FLAG_QH 0x1
184 #define offsetof( s, m ) ( ( ULONG )( &( ( s* )0 )->m ) )
187 #define struct_ptr( meMBER_ptr, stRUCT_name, meMBER_name ) \
188 ( ( stRUCT_name* ) ( ( (CHAR*)( meMBER_ptr ) ) - offsetof( stRUCT_name, meMBER_name ) ) )
190 #define dev_state( pdEV ) ( ( pdEV )->flags & USB_DEV_STATE_MASK )
192 #define dev_class( pdev ) ( pdev->flags & USB_DEV_CLASS_MASK )
194 #define uhci_from_hcd( hCD ) ( struct_ptr( ( hCD ), UHCI_DEV, hcd_interf ) )
195 #define uhci_from_dev( dEV ) ( struct_ptr( ( dEV->hcd ), UHCI_DEV, hcd_interf ) )
197 typedef struct _TD_EXTENSION
199 LIST_ENTRY vert_link
; // urb will use this to link qh and tds
200 LIST_ENTRY hori_link
;
202 struct _UHCI_TD
*ptd
; //link to is companion td, constant since initialized
204 } TD_EXTENSION
, *PTD_EXTENSION
;
206 typedef struct _UHCI_TD
208 /* Hardware fields */
214 /* Software fields */
218 struct _UHCI_TD_POOL
*pool
; //pool this td belongs to
220 } UHCI_TD
, *PUHCI_TD
;
222 typedef struct _UHCI_TD_POOL
225 LIST_ENTRY pool_link
; //link to next and prev td pool
226 PUHCI_TD td_array
[ sizeof( UHCI_TD
) * UHCI_MAX_POOL_TDS
/ PAGE_SIZE
]; //would be allcated in common buffer
227 PHYSICAL_ADDRESS logic_addr
[ sizeof( UHCI_TD
) * UHCI_MAX_POOL_TDS
/ PAGE_SIZE
]; //logical addr of the array
229 PTD_EXTENSION tde_array
;
230 LIST_ENTRY free_que
; //list of free tds
231 LONG free_count
; //free tds in this pool
232 LONG total_count
; //total count of the tds
233 PADAPTER_OBJECT padapter
;
235 } UHCI_TD_POOL
, *PUHCI_TD_POOL
;
246 ); //add tds till pnext == NULL
250 PUHCI_TD_POOL ptd_pool
256 ); //test whether the pool is all free
268 typedef struct _UHCI_TD_POOL_LIST
270 LIST_ENTRY busy_pools
;
271 KSPIN_LOCK pool_lock
;
272 LONG free_tds
; //free tds in all the pool
273 LONG free_count
; //free pool count
274 LIST_ENTRY free_pools
;
275 UHCI_TD_POOL pool_array
[UHCI_MAX_TD_POOLS
]; //max transfer is 640k
277 } UHCI_TD_POOL_LIST
, *PUHCI_TD_POOL_LIST
;
281 PUHCI_TD_POOL_LIST pool_list
,
282 PADAPTER_OBJECT padapter
286 destroy_td_pool_list(
287 PUHCI_TD_POOL_LIST pool_list
292 PUHCI_TD_POOL_LIST pool_list
,
298 PUHCI_TD_POOL_LIST pool_list
303 PUHCI_TD_POOL_LIST pool_list
308 PUHCI_TD_POOL_LIST pool_list
313 PUHCI_TD_POOL_LIST pool_list
,
318 PUHCI_TD_POOL_LIST pool_list
,
320 ); //add tds till pnext == NULL
324 PUHCI_TD_POOL_LIST pool_list
329 PUHCI_TD_POOL_LIST pool_list
,
335 PUHCI_TD_POOL_LIST pool_list
,
339 typedef struct _UHCI_QH
341 /* Hardware fields */
342 ULONG link
; // Next queue
343 ULONG element
; // Queue element pointer
345 /* Software fields */
346 ULONG phy_addr
; //constant since initialized
347 struct _QH_EXTENSION
*pqhe
;
349 } UHCI_QH
, *PUHCI_QH
;
351 typedef struct _QH_EXTENSION
354 LIST_ENTRY vert_link
;
355 LIST_ENTRY hori_link
;
357 PUHCI_QH pqh
; //constant since initialized
360 } QH_EXTENSION
, *PQH_EXTENSION
;
362 typedef struct _UHCI_QH_POOL
366 PHYSICAL_ADDRESS logic_addr
; //logical addr of the array
368 PQH_EXTENSION qhe_array
;
372 KSPIN_LOCK pool_lock
;
373 PADAPTER_OBJECT padapter
; //we need this garbage for allocation
375 } UHCI_QH_POOL
, *PUHCI_QH_POOL
;
381 PADAPTER_OBJECT padapter
388 ); //add qhs till pnext == NULL
413 * Search tree for determining where <interval> fits in the
416 * An interrupt request should be placed into the slowest skelqh[]
417 * which meets the interval/period/frequency requirement.
418 * An interrupt request is allowed to be faster than <interval> but not slower.
420 * For a given <interval>, this function returns the appropriate/matching
421 * skelqh[] index value.
423 * NOTE: For UHCI, we don't really need int256_qh since the maximum interval
424 * is 255 ms. However, we do need an int1_qh since 1 is a valid interval
425 * and we should meet that frequency when requested to do so.
426 * This will require some change(s) to the UHCI skeleton.
429 static int __interval_to_skel(int interval
)
434 return 0; /* int1 for 0-1 ms */
435 return 1; /* int2 for 2-3 ms */
438 return 2; /* int4 for 4-7 ms */
439 return 3; /* int8 for 8-15 ms */
443 return 4; /* int16 for 16-31 ms */
444 return 5; /* int32 for 32-63 ms */
447 return 6; /* int64 for 64-127 ms */
448 return 7; /* int128 for 128-255 ms (Max.) */
452 #define USB_ENDP_FLAG_BUSY_MASK 0x0000ff00
453 #define USB_ENDP_FLAG_STAT_MASK 0xff
454 #define USB_ENDP_FLAG_STALL 0x01
455 #define USB_ENDP_FLAG_DATATOGGLE 0x80000000
456 #define USB_ENDP_FLAG_DEFAULT_ENDP 0x40000000
458 #define usb_endp_busy_count( peNDP ) \
459 ( ( ( peNDP )->flags & USB_ENDP_FLAG_BUSY_MASK ) >> 8 )
461 #define usb_endp_busy_count_inc( peNDP ) \
462 ( peNDP->flags = ( ( ( ( usb_endp_busy_count( peNDP ) + 1 ) << 8 ) & USB_ENDP_FLAG_BUSY_MASK ) | \
463 ( ( peNDP )->flags & ~USB_ENDP_FLAG_BUSY_MASK ) ) )
465 #define usb_endp_busy_count_dec( peNDP ) \
466 ( peNDP->flags = ( ( ( ( usb_endp_busy_count( peNDP ) - 1 ) << 8 ) & USB_ENDP_FLAG_BUSY_MASK )| \
467 ( ( peNDP )->flags & ~USB_ENDP_FLAG_BUSY_MASK ) ) )
469 typedef struct _USB_ENDPOINT
471 ULONG flags
; //toggle | busy-count | stall | default-endp; busy count( usually 1 when busy, may be greater if iso endp )
472 LIST_ENTRY urb_list
; //pending urb queue
474 struct _USB_INTERFACE
*pusb_if
;
475 struct _USB_ENDPOINT_DESC
*pusb_endp_desc
;
477 } USB_ENDPOINT
, *PUSB_ENDPOINT
;
479 #define MAX_ENDPS_PER_IF 10
481 typedef struct _USB_INTERFACE
484 USB_ENDPOINT endp
[MAX_ENDPS_PER_IF
];
487 struct _USB_CONFIGURATION
*pusb_config
;
488 PUSB_INTERFACE_DESC pusb_if_desc
;
490 struct _USB_DRIVER
*pif_drv
; //for hub_dev use
494 LIST_ENTRY altif_list
;
497 } USB_INTERFACE
, *PUSB_INTERFACE
;
499 #define MAX_INTERFACES_PER_CONFIG 4
500 #define MAX_CONFIGS_PER_DEV 4
502 typedef struct _USB_CONFIGURATION
504 //only for active configuration
505 struct _USB_CONFIGURATION_DESC
*pusb_config_desc
;
507 USB_INTERFACE interf
[MAX_INTERFACES_PER_CONFIG
];
508 struct _USB_DEV
*pusb_dev
;
510 } USB_CONFIGURATION
, *PUSB_CONFIGURATION
;
513 KIRQL _pending_endp_lock_old_irql=0, _pending_endp_list_lock_old_irql=0, _dev_lock_old_irql=0, old_irql=0;
515 #define USE_BASIC_IRQL \
516 KIRQL _pending_endp_list_lock_old_irql=0, _dev_lock_old_irql=0;
518 #define USE_NON_PENDING_IRQL \
519 KIRQL _dev_lock_old_irql=0, old_irql=0;
521 #define USE_BASIC_NON_PENDING_IRQL \
522 KIRQL _dev_lock_old_irql=0;
525 #define USB_DEV_STATE_MASK ( 0xff << 8 )
526 #define USB_DEV_STATE_POWERED ( 0x01 << 8 )
527 #define USB_DEV_STATE_RESET ( 0x02 << 8 )
528 #define USB_DEV_STATE_ADDRESSED ( 0x03 << 8 )
529 #define USB_DEV_STATE_FIRST_CONFIG ( 0x04 << 8 )
530 #define USB_DEV_STATE_RECONFIG ( 0x05 << 8 )
531 #define USB_DEV_STATE_CONFIGURED ( 0x06 << 8 )
532 #define USB_DEV_STATE_SUSPENDED ( 0x07 << 8 )
533 #define USB_DEV_STATE_BEFORE_ZOMB ( 0x08 << 8 )
534 #define USB_DEV_STATE_ZOMB ( 0x09 << 8 )
536 #define USB_DEV_CLASS_MASK ( 0xff << 16 )
537 #define USB_DEV_CLASS_HUB ( USB_CLASS_HUB << 16 )
538 #define USB_DEV_CLASS_MASSSTOR ( USB_CLASS_MASS_STORAGE << 16 )
539 #define USB_DEV_CLASS_ROOT_HUB ( ( USB_CLASS_VENDOR_SPEC - 2 ) << 16 )
540 #define USB_DEV_CLASS_SCANNER ( ( USB_DEV_CLASS_ROOT_HUB - 1 ) << 16 )
542 #define USB_DEV_FLAG_HIGH_SPEED 0x20 // high speed dev for usb2.0
543 #define USB_DEV_FLAG_LOW_SPEED 0x40 // note: this bit is shared in urb->pipe
544 #define USB_DEV_FLAG_IF_DEV 0x01 // this dev is a virtual dev, that is a interface
546 #define lock_dev( pdev, at_dpc ) \
549 cur_irql = KeGetCurrentIrql();\
550 if( cur_irql == DISPATCH_LEVEL )\
552 KeAcquireSpinLockAtDpcLevel( &pdev->dev_lock );\
553 _dev_lock_old_irql = DISPATCH_LEVEL;\
555 else if( cur_irql < DISPATCH_LEVEL )\
556 KeAcquireSpinLock( &pdev->dev_lock, &_dev_lock_old_irql );\
561 #define unlock_dev( pdev, from_dpc ) \
563 if( _dev_lock_old_irql == DISPATCH_LEVEL )\
564 KeReleaseSpinLockFromDpcLevel( &pdev->dev_lock );\
565 else if( _dev_lock_old_irql < DISPATCH_LEVEL )\
566 KeReleaseSpinLock( &pdev->dev_lock, _dev_lock_old_irql );\
571 typedef struct _USB_DEV
573 LIST_ENTRY dev_link
; //for dev-list
576 PDEVICE_OBJECT dev_obj
;
577 ULONG flags
; //class | cur_state | low speed
578 LONG ref_count
; //client count
580 UCHAR dev_addr
; //usb addr
581 ULONG dev_id
; //will be used to compose dev handle
583 struct _USB_DEV
*parent_dev
;
584 UCHAR port_idx
; //parent hub's port idx, to which the dev attached
586 struct _HCD
*hcd
; //point to the hcd the dev belongs to
588 USB_ENDPOINT default_endp
; //control endp. its interfac pointer is to the first interface
592 struct _USB_DEVICE_DESC
*pusb_dev_desc
;
594 UCHAR active_config_idx
;
595 PUSB_CONFIGURATION usb_config
; //the active configuration
597 struct _USB_DRIVER
*dev_driver
;
601 LONG time_out_count
; //default pipe error counter, three time-outs will cause the dev not function
602 LONG error_count
; //usb transfer error counter for statics only
604 } USB_DEV
, *PUSB_DEV
;
606 // pending endpoint pool definitions
608 #define UHCI_MAX_PENDING_ENDPS 32
610 typedef struct _UHCI_PENDING_ENDP
612 LIST_ENTRY endp_link
;
615 } UHCI_PENDING_ENDP
, *PUHCI_PENDING_ENDP
;
617 typedef struct _UHCI_PENDING_ENDP_POOL
619 PUHCI_PENDING_ENDP pending_endp_array
;
623 KSPIN_LOCK pool_lock
;
625 } UHCI_PENDING_ENDP_POOL
, *PUHCI_PENDING_ENDP_POOL
;
628 init_pending_endp_pool(
629 PUHCI_PENDING_ENDP_POOL pool
634 PUHCI_PENDING_ENDP_POOL pool
,
635 PUHCI_PENDING_ENDP pending_endp
640 PUHCI_PENDING_ENDP_POOL pool
,
645 destroy_pending_endp_pool(
646 PUHCI_PENDING_ENDP_POOL pool
649 // pool type is PUHCI_PENDING_ENDP_POOL
650 #define lock_pending_endp_pool( pool ) \
652 KeAcquireSpinLock( &pool->pool_lock, &_pending_endp_lock_old_irql );\
655 #define unlock_pending_endp_pool( pool ) \
657 KeReleaseSpinLock( &pool->pool_lock, &_pending_endp_lock_old_irql );\
661 // end of pending endpoint pool
662 typedef struct _FRAME_LIST_CPU_ENTRY
666 } FRAME_LIST_CPU_ENTRY
, *PFRAME_LIST_CPU_ENTRY
;
668 #define uhci_public_res_lock pending_endp_list_lock
669 #define uhci_status( _uhci_ ) ( READ_PORT_USHORT( ( PUSHORT )( ( _uhci_ )->port_base + USBSTS ) ) )
673 PHYSICAL_ADDRESS uhci_reg_base
; // io space
677 PHYSICAL_ADDRESS io_buf_logic_addr
;
680 PHYSICAL_ADDRESS frame_list_logic_addr
;
682 KSPIN_LOCK frame_list_lock
; //run at DIRQL
684 PFRAME_LIST_CPU_ENTRY frame_list_cpu
;
685 LIST_HEAD urb_list
; //active urb-list
686 PUHCI_TD skel_td
[UHCI_MAX_SKELTDS
];
687 PUHCI_QH skel_qh
[UHCI_MAX_SKELQHS
]; //skeltons
691 UHCI_TD_POOL_LIST td_pool
;
692 UHCI_QH_POOL qh_pool
;
695 //for iso and int bandwidth claim, bandwidth schedule
696 KSPIN_LOCK pending_endp_list_lock
; //lock to access the following two
697 LIST_HEAD pending_endp_list
;
698 UHCI_PENDING_ENDP_POOL pending_endp_pool
;
700 LONG fsbr_cnt
; //used to record number of fsbr users
702 KTIMER reset_timer
; //used to reset the host controller
704 //struct _USB_DEV_MANAGER dev_mgr; //it is in hcd_interf
705 struct _DEVICE_EXTENSION
*pdev_ext
;
707 PUSB_DEV root_hub
; //root hub
710 } UHCI_DEV
, *PUHCI_DEV
;
712 #define lock_pending_endp_list( list_lock ) \
714 KeAcquireSpinLock( list_lock, &_pending_endp_list_lock_old_irql );\
717 #define unlock_pending_endp_list( list_lock ) \
719 KeReleaseSpinLock( list_lock, _pending_endp_list_lock_old_irql );\
721 typedef struct _UHCI_INTERRUPT
727 } UHCI_INTERRUPT
, *PUHCI_INTERRUPT
;
729 typedef struct _UHCI_PORT
731 PHYSICAL_ADDRESS Start
;
734 } UHCI_PORT
, *PUHCI_PORT
;
736 typedef NTSTATUS ( *PDISPATCH_ROUTINE
)( PDEVICE_OBJECT dev_obj
, PIRP irp
);
738 #define NTDEV_TYPE_HCD 1
739 #define NTDEV_TYPE_CLIENT_DEV 2
741 typedef struct _DEVEXT_HEADER
744 PDISPATCH_ROUTINE dispatch
;
745 PDRIVER_STARTIO start_io
;
747 struct _USB_DEV_MANAGER
*dev_mgr
; //mainly for use by cancel irp
749 } DEVEXT_HEADER
, *PDEVEXT_HEADER
;
751 typedef struct _DEVICE_EXTENSION
753 //struct _USB_DEV_MANAGER *pdev_mgr;
754 DEVEXT_HEADER dev_ext_hdr
;
755 PDEVICE_OBJECT pdev_obj
;
756 PDRIVER_OBJECT pdrvr_obj
;
760 PADAPTER_OBJECT padapter
;
762 PCM_RESOURCE_LIST res_list
;
763 ULONG pci_addr
; // bus number | slot number | funciton number
764 UHCI_INTERRUPT res_interrupt
;
767 PKINTERRUPT uhci_int
;
770 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
773 #define ListFirst( heAD, firST) \
775 if( IsListEmpty( ( heAD ) ) )\
778 firST = ( heAD )->Flink;\
781 #define ListNext( heAD, curreNT, neXT) \
783 if( IsListEmpty( ( heAD ) ) == FALSE )\
785 neXT = (curreNT)->Flink;\
793 #define ListPrev( heAD, curreNT, prEV) \
795 if( IsListEmpty( ( heAD ) ) == FALSE )\
797 prEV = (curreNT)->Blink;\
804 #define ListFirstPrev( heAD, firST) \
806 if( IsListEmpty( ( heAD ) ) )\
809 firST = ( heAD )->Blink;\
812 #define MergeList( liST1, liST2 )\
814 PLIST_ENTRY taIL1, taIL2;\
815 if( IsListEmpty( liST2 ) == TRUE )\
817 InsertTailList( liST1, liST2 );\
819 else if( IsListEmpty( liST1 ) == TRUE )\
821 InsertTailList( liST2, liST1 );\
825 ListFirstPrev( liST1, taIL1 );\
826 ListFirstPrev( liST2, taIL2 );\
828 taIL1->Flink = ( liST2 );\
829 ( liST2 )->Blink = taIL1;\
831 taIL2->Flink = ( liST1 );\
832 ( liST1 )->Blink = taIL2;\
838 PUHCI_TD_POOL_LIST pool_list
,
844 PUHCI_TD_POOL_LIST pool_list
,
851 PADAPTER_OBJECT padapter
859 // funcitons exported to dev-manager
883 uhci_flush_adapter_buf()
899 //must have dev_lock acquired
901 uhci_internal_submit_bulk(
907 uhci_internal_submit_iso(
913 uhci_internal_submit_ctrl(
919 uhci_internal_submit_int(
925 uhci_remove_bulk_from_schedule(
930 #define uhci_remove_ctrl_from_schedule uhci_remove_bulk_from_schedule
933 uhci_remove_iso_from_schedule(
939 uhci_remove_int_from_schedule(
945 uhci_remove_urb_from_schedule(
951 uhci_is_xfer_finished( //will set urb error code here
974 uhci_insert_urb_schedule(
980 uhci_claim_bandwidth(
987 uhci_process_pending_endp(
1000 uhci_generic_urb_completion(
1005 // the following are NT driver definitions
1008 #define UHCI_DEVICE_NAME "\\Device\\UHCI"
1010 // File system device name. When you execute a CreateFile call to open the
1011 // device, use "\\.\GpdDev", or, given C's conversion of \\ to \, use
1014 #define DOS_DEVICE_NAME "\\DosDevices\\UHCI"
1017 #define CLR_RH_PORTSTAT( port_idx, x ) \
1020 addr = ( PUSHORT )( uhci->port_base + port_idx ); \
1021 status = READ_PORT_USHORT( addr ); \
1022 status = ( status & 0xfff5 ) & ~( x ); \
1023 WRITE_PORT_USHORT( addr, ( USHORT )status ); \
1026 #define SET_RH_PORTSTAT( port_idx, x ) \
1029 addr = ( PUSHORT )( uhci->port_base + port_idx ); \
1030 status = READ_PORT_USHORT( addr ); \
1031 status = ( status & 0xfff5 ) | ( x ); \
1032 WRITE_PORT_USHORT( addr, ( USHORT )status ); \
1035 //this is for dispatch routine
1036 #define EXIT_DISPATCH( nTstatUs, iRp)\
1038 if( nTstatUs != STATUS_PENDING)\
1040 iRp->IoStatus.Status = nTstatUs;\
1041 IoCompleteRequest( iRp, IO_NO_INCREMENT);\
1044 IoMarkIrpPending( iRp);\