Subversion Repositories Kolibri OS

Rev

Rev 3725 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3725 Rev 3908
1
; Code for OHCI controllers.
1
; Code for OHCI controllers.
2
; Note: it should be moved to an external driver,
2
; Note: it should be moved to an external driver,
3
; it was convenient to have this code compiled into the kernel during initial
3
; it was convenient to have this code compiled into the kernel during initial
4
; development, but there are no reasons to keep it here.
4
; development, but there are no reasons to keep it here.
5
 
5
 
6
; =============================================================================
6
; =============================================================================
7
; ================================= Constants =================================
7
; ================================= Constants =================================
8
; =============================================================================
8
; =============================================================================
9
; OHCI register declarations
9
; OHCI register declarations
10
; All of the registers should be read and written as Dwords.
10
; All of the registers should be read and written as Dwords.
11
; Partition 1. Control and Status registers.
11
; Partition 1. Control and Status registers.
12
OhciRevisionReg         = 0
12
OhciRevisionReg         = 0
13
OhciControlReg          = 4
13
OhciControlReg          = 4
14
OhciCommandStatusReg    = 8
14
OhciCommandStatusReg    = 8
15
OhciInterruptStatusReg  = 0Ch
15
OhciInterruptStatusReg  = 0Ch
16
OhciInterruptEnableReg  = 10h
16
OhciInterruptEnableReg  = 10h
17
OhciInterruptDisableReg = 14h
17
OhciInterruptDisableReg = 14h
18
; Partition 2. Memory Pointer registers.
18
; Partition 2. Memory Pointer registers.
19
OhciHCCAReg             = 18h
19
OhciHCCAReg             = 18h
20
OhciPeriodCurrentEDReg  = 1Ch
20
OhciPeriodCurrentEDReg  = 1Ch
21
OhciControlHeadEDReg    = 20h
21
OhciControlHeadEDReg    = 20h
22
OhciControlCurrentEDReg = 24h
22
OhciControlCurrentEDReg = 24h
23
OhciBulkHeadEDReg       = 28h
23
OhciBulkHeadEDReg       = 28h
24
OhciBulkCurrentEDReg    = 2Ch
24
OhciBulkCurrentEDReg    = 2Ch
25
OhciDoneHeadReg         = 30h
25
OhciDoneHeadReg         = 30h
26
; Partition 3. Frame Counter registers.
26
; Partition 3. Frame Counter registers.
27
OhciFmIntervalReg       = 34h
27
OhciFmIntervalReg       = 34h
28
OhciFmRemainingReg      = 38h
28
OhciFmRemainingReg      = 38h
29
OhciFmNumberReg         = 3Ch
29
OhciFmNumberReg         = 3Ch
30
OhciPeriodicStartReg    = 40h
30
OhciPeriodicStartReg    = 40h
31
OhciLSThresholdReg      = 44h
31
OhciLSThresholdReg      = 44h
32
; Partition 4. Root Hub registers.
32
; Partition 4. Root Hub registers.
33
OhciRhDescriptorAReg    = 48h
33
OhciRhDescriptorAReg    = 48h
34
OhciRhDescriptorBReg    = 4Ch
34
OhciRhDescriptorBReg    = 4Ch
35
OhciRhStatusReg         = 50h
35
OhciRhStatusReg         = 50h
36
OhciRhPortStatusReg     = 54h
36
OhciRhPortStatusReg     = 54h
37
 
37
 
38
; =============================================================================
38
; =============================================================================
39
; ================================ Structures =================================
39
; ================================ Structures =================================
40
; =============================================================================
40
; =============================================================================
41
 
41
 
42
; OHCI-specific part of a pipe descriptor.
42
; OHCI-specific part of a pipe descriptor.
43
; * This structure corresponds to the Endpoint Descriptor aka ED from the OHCI
43
; * This structure corresponds to the Endpoint Descriptor aka ED from the OHCI
44
;   specification.
44
;   specification.
45
; * The hardware requires 16-bytes alignment of the hardware part.
45
; * The hardware requires 16-bytes alignment of the hardware part.
46
;   Since the allocator (usb_allocate_common) allocates memory sequentially
46
;   Since the allocator (usb_allocate_common) allocates memory sequentially
47
;   from page start (aligned on 0x1000 bytes), block size for the allocator
47
;   from page start (aligned on 0x1000 bytes), block size for the allocator
48
;   must be divisible by 16; usb1_allocate_endpoint ensures this.
48
;   must be divisible by 16; usb1_allocate_endpoint ensures this.
49
struct ohci_pipe
49
struct ohci_pipe
50
; All addresses are physical.
50
; All addresses are physical.
51
Flags           dd      ?
51
Flags           dd      ?
52
; 1. Lower 7 bits (bits 0-6) are FunctionAddress. This is the USB address of
52
; 1. Lower 7 bits (bits 0-6) are FunctionAddress. This is the USB address of
53
;    the function containing the endpoint that this ED controls.
53
;    the function containing the endpoint that this ED controls.
54
; 2. Next 4 bits (bits 7-10) are EndpointNumber. This is the USB address of
54
; 2. Next 4 bits (bits 7-10) are EndpointNumber. This is the USB address of
55
;    the endpoint within the function.
55
;    the endpoint within the function.
56
; 3. Next 2 bits (bits 11-12) are Direction. This 2-bit field indicates the
56
; 3. Next 2 bits (bits 11-12) are Direction. This 2-bit field indicates the
57
;    direction of data flow: 1 = IN, 2 = OUT. If neither IN nor OUT is
57
;    direction of data flow: 1 = IN, 2 = OUT. If neither IN nor OUT is
58
;    specified, then the direction is determined from the PID field of the TD.
58
;    specified, then the direction is determined from the PID field of the TD.
59
;    For CONTROL endpoints, the transfer direction is different
59
;    For CONTROL endpoints, the transfer direction is different
60
;    for different transfers, so the value of this field is 0
60
;    for different transfers, so the value of this field is 0
61
;    (3 would have the same effect) and the actual direction
61
;    (3 would have the same effect) and the actual direction
62
;    of one transfer is encoded in the Transfer Descriptor.
62
;    of one transfer is encoded in the Transfer Descriptor.
63
; 4. Next bit (bit 13) is Speed bit. It indicates the speed of the endpoint:
63
; 4. Next bit (bit 13) is Speed bit. It indicates the speed of the endpoint:
64
;    full-speed (S = 0) or low-speed (S = 1).
64
;    full-speed (S = 0) or low-speed (S = 1).
65
; 5. Next bit (bit 14) is sKip bit. When this bit is set, the hardware
65
; 5. Next bit (bit 14) is sKip bit. When this bit is set, the hardware
66
;    continues on to the next ED on the list without attempting access
66
;    continues on to the next ED on the list without attempting access
67
;    to the TD queue or issuing any USB token for the endpoint.
67
;    to the TD queue or issuing any USB token for the endpoint.
68
;    Always cleared.
68
;    Always cleared.
69
; 6. Next bit (bit 15) is Format bit. It must be 0 for Control, Bulk and
69
; 6. Next bit (bit 15) is Format bit. It must be 0 for Control, Bulk and
70
;    Interrupt endpoints and 1 for Isochronous endpoints.
70
;    Interrupt endpoints and 1 for Isochronous endpoints.
71
; 7. Next 11 bits (bits 16-26) are MaximumPacketSize. This field indicates
71
; 7. Next 11 bits (bits 16-26) are MaximumPacketSize. This field indicates
72
;    the maximum number of bytes that can be sent to or received from the
72
;    the maximum number of bytes that can be sent to or received from the
73
;    endpoint in a single data packet.
73
;    endpoint in a single data packet.
74
TailP           dd      ?
74
TailP           dd      ?
75
; Physical address of the tail descriptor in the TD queue.
75
; Physical address of the tail descriptor in the TD queue.
76
; The descriptor itself is not in the queue. See also HeadP.
76
; The descriptor itself is not in the queue. See also HeadP.
77
HeadP           dd      ?
77
HeadP           dd      ?
78
; 1. First bit (bit 0) is Halted bit. This bit is set by the hardware to
78
; 1. First bit (bit 0) is Halted bit. This bit is set by the hardware to
79
;    indicate that processing of the TD queue on the endpoint is halted.
79
;    indicate that processing of the TD queue on the endpoint is halted.
80
; 2. Second bit (bit 1) is toggleCarry bit. Whenever a TD is retired, this
80
; 2. Second bit (bit 1) is toggleCarry bit. Whenever a TD is retired, this
81
;    bit is written to contain the last data toggle value from the retired TD.
81
;    bit is written to contain the last data toggle value from the retired TD.
82
; 3. Next two bits (bits 2-3) are reserved and always zero.
82
; 3. Next two bits (bits 2-3) are reserved and always zero.
83
; 4. With masked 4 lower bits, this is HeadP itself: physical address of the
83
; 4. With masked 4 lower bits, this is HeadP itself: physical address of the
84
;    head descriptor in the TD queue, that is, next TD to be processed for this
84
;    head descriptor in the TD queue, that is, next TD to be processed for this
85
;    endpoint. Note that a TD must be 16-bytes aligned.
85
;    endpoint. Note that a TD must be 16-bytes aligned.
86
;    Empty queue is characterized by the condition HeadP == TailP.
86
;    Empty queue is characterized by the condition HeadP == TailP.
87
NextED          dd      ?
87
NextED          dd      ?
88
; If nonzero, then this entry is a physical address of the next ED to be
88
; If nonzero, then this entry is a physical address of the next ED to be
89
; processed. See also the description before NextVirt field of the usb_pipe
89
; processed. See also the description before NextVirt field of the usb_pipe
90
; structure. Additionally to that description, the following is specific for
90
; structure. Additionally to that description, the following is specific for
91
; the OHCI controller:
91
; the OHCI controller:
92
; * n=5, N=32, there are 32 "leaf" periodic lists.
92
; * n=5, N=32, there are 32 "leaf" periodic lists.
93
; * The 1ms periodic list also serves Isochronous endpoints, which should be
93
; * The 1ms periodic list also serves Isochronous endpoints, which should be
94
;   in the end of the list.
94
;   in the end of the list.
95
; * There is no "next" list for Bulk and Control lists, they are processed
95
; * There is no "next" list for Bulk and Control lists, they are processed
96
;   separately from others.
96
;   separately from others.
97
; * There is no "next" list for Periodic list for 1ms interval.
97
; * There is no "next" list for Periodic list for 1ms interval.
98
ends
98
ends
99
 
99
 
100
; This structure describes the static head of every list of pipes.
100
; This structure describes the static head of every list of pipes.
101
; The hardware requires 16-bytes alignment of this structure.
101
; The hardware requires 16-bytes alignment of this structure.
102
; All instances of this structure are located sequentially in uhci_controller,
102
; All instances of this structure are located sequentially in uhci_controller,
103
; uhci_controller is page-aligned, so it is sufficient to make this structure
103
; uhci_controller is page-aligned, so it is sufficient to make this structure
104
; 16-bytes aligned and verify that the first instance is 16-bytes aligned
104
; 16-bytes aligned and verify that the first instance is 16-bytes aligned
105
; inside uhci_controller.
105
; inside uhci_controller.
106
struct ohci_static_ep
106
struct ohci_static_ep
107
Flags           dd      ?
107
Flags           dd      ?
108
; Same as ohci_pipe.Flags.
108
; Same as ohci_pipe.Flags.
109
; sKip bit is set, so the hardware ignores other fields except NextED.
109
; sKip bit is set, so the hardware ignores other fields except NextED.
110
                dd      ?
110
                dd      ?
111
; Corresponds to ohci_pipe.TailP. Not used.
111
; Corresponds to ohci_pipe.TailP. Not used.
112
NextList        dd      ?
112
NextList        dd      ?
113
; Virtual address of the next list.
113
; Virtual address of the next list.
114
NextED          dd      ?
114
NextED          dd      ?
115
; Same as ohci_pipe.NextED.
115
; Same as ohci_pipe.NextED.
116
SoftwarePart    rd      sizeof.usb_static_ep/4
116
SoftwarePart    rd      sizeof.usb_static_ep/4
117
; Software part, common for all controllers.
117
; Software part, common for all controllers.
118
                dd      ?
118
                dd      ?
119
; Padding for 16-bytes alignment.
119
; Padding for 16-bytes alignment.
120
ends
120
ends
121
 
121
 
122
if sizeof.ohci_static_ep mod 16
122
if sizeof.ohci_static_ep mod 16
123
.err ohci_static_ep must be 16-bytes aligned
123
.err ohci_static_ep must be 16-bytes aligned
124
end if
124
end if
125
 
125
 
126
; OHCI-specific part of controller data.
126
; OHCI-specific part of controller data.
127
; * The structure describes the memory area used for controller data,
127
; * The structure describes the memory area used for controller data,
128
;   additionally to the registers of the controller.
128
;   additionally to the registers of the controller.
129
; * The structure includes two parts, the hardware part and the software part.
129
; * The structure includes two parts, the hardware part and the software part.
130
; * The hardware part consists of first 256 bytes and corresponds to
130
; * The hardware part consists of first 256 bytes and corresponds to
131
;   the HCCA from OHCI specification.
131
;   the HCCA from OHCI specification.
132
; * The hardware requires 256-bytes alignment of the hardware part, so
132
; * The hardware requires 256-bytes alignment of the hardware part, so
133
;   the entire descriptor must be 256-bytes aligned.
133
;   the entire descriptor must be 256-bytes aligned.
134
;   This structure is allocated with kernel_alloc (see usb_init_controller),
134
;   This structure is allocated with kernel_alloc (see usb_init_controller),
135
;   this gives page-aligned data.
135
;   this gives page-aligned data.
136
; * The controller is described by both ohci_controller and usb_controller
136
; * The controller is described by both ohci_controller and usb_controller
137
;   structures, for each controller there is one ohci_controller and one
137
;   structures, for each controller there is one ohci_controller and one
138
;   usb_controller structure. These structures are located sequentially
138
;   usb_controller structure. These structures are located sequentially
139
;   in the memory: beginning from some page start, there is ohci_controller
139
;   in the memory: beginning from some page start, there is ohci_controller
140
;   structure - this enforces hardware alignment requirements - and then
140
;   structure - this enforces hardware alignment requirements - and then
141
;   usb_controller structure.
141
;   usb_controller structure.
142
; * The code keeps pointer to usb_controller structure. The ohci_controller
142
; * The code keeps pointer to usb_controller structure. The ohci_controller
143
;   structure is addressed as [ptr + ohci_controller.field - sizeof.ohci_controller].
143
;   structure is addressed as [ptr + ohci_controller.field - sizeof.ohci_controller].
144
struct ohci_controller
144
struct ohci_controller
145
; ------------------------------ hardware fields ------------------------------
145
; ------------------------------ hardware fields ------------------------------
146
InterruptTable  rd      32
146
InterruptTable  rd      32
147
; Pointers to interrupt EDs. The hardware starts processing of periodic lists
147
; Pointers to interrupt EDs. The hardware starts processing of periodic lists
148
; within the frame N from the ED pointed to by [InterruptTable+(N and 31)*4].
148
; within the frame N from the ED pointed to by [InterruptTable+(N and 31)*4].
149
; See also the description of periodic lists inside ohci_pipe structure.
149
; See also the description of periodic lists inside ohci_pipe structure.
150
FrameNumber     dw      ?
150
FrameNumber     dw      ?
151
; The current frame number. This field is written by hardware only.
151
; The current frame number. This field is written by hardware only.
152
; This field is read by ohci_process_deferred and ohci_irq to
152
; This field is read by ohci_process_deferred and ohci_irq to
153
; communicate when control/bulk processing needs to be temporarily
153
; communicate when control/bulk processing needs to be temporarily
154
; stopped/restarted.
154
; stopped/restarted.
155
                dw      ?
155
                dw      ?
156
; Padding. Written as zero at every update of FrameNumber.
156
; Padding. Written as zero at every update of FrameNumber.
157
DoneHead        dd      ?
157
DoneHead        dd      ?
158
; Physical pointer to the start of Done Queue.
158
; Physical pointer to the start of Done Queue.
159
; When the hardware updates this field, it sets bit 0 to one if there is
159
; When the hardware updates this field, it sets bit 0 to one if there is
160
; unmasked interrupt pending.
160
; unmasked interrupt pending.
161
                rb      120
161
                rb      120
162
; Reserved for the hardware.
162
; Reserved for the hardware.
163
; ------------------------------ software fields ------------------------------
163
; ------------------------------ software fields ------------------------------
164
IntEDs          ohci_static_ep
164
IntEDs          ohci_static_ep
165
                rb      62 * sizeof.ohci_static_ep
165
                rb      62 * sizeof.ohci_static_ep
166
; Heads of 63 Periodic lists, see the description in usb_pipe.
166
; Heads of 63 Periodic lists, see the description in usb_pipe.
167
ControlED       ohci_static_ep
167
ControlED       ohci_static_ep
168
; Head of Control list, see the description in usb_pipe.
168
; Head of Control list, see the description in usb_pipe.
169
BulkED          ohci_static_ep
169
BulkED          ohci_static_ep
170
; Head of Bulk list, see the description in usb_pipe.
170
; Head of Bulk list, see the description in usb_pipe.
171
MMIOBase        dd      ?
171
MMIOBase        dd      ?
172
; Virtual address of memory-mapped area with OHCI registers OhciXxxReg.
172
; Virtual address of memory-mapped area with OHCI registers OhciXxxReg.
173
PoweredUp       db      ?
173
PoweredUp       db      ?
174
; 1 in normal work, 0 during early phases of the initialization.
174
; 1 in normal work, 0 during early phases of the initialization.
175
; This field is initialized to zero during memory allocation
175
; This field is initialized to zero during memory allocation
176
; (see usb_init_controller), set to one by ohci_init when ports of the root hub
176
; (see usb_init_controller), set to one by ohci_init when ports of the root hub
177
; are powered up, so connect/disconnect events can be handled.
177
; are powered up, so connect/disconnect events can be handled.
178
                rb      3 ; alignment
178
                rb      3 ; alignment
179
DoneList        dd      ?
179
DoneList        dd      ?
180
; List of descriptors which were processed by the controller and now need
180
; List of descriptors which were processed by the controller and now need
181
; to be finalized.
181
; to be finalized.
182
DoneListEndPtr  dd      ?
182
DoneListEndPtr  dd      ?
183
; Pointer to dword which should receive a pointer to the next item in DoneList.
183
; Pointer to dword which should receive a pointer to the next item in DoneList.
184
; If DoneList is empty, this is a pointer to DoneList itself;
184
; If DoneList is empty, this is a pointer to DoneList itself;
185
; otherwise, this is a pointer to NextTD field of the last item in DoneList.
185
; otherwise, this is a pointer to NextTD field of the last item in DoneList.
186
ends
186
ends
187
 
187
 
188
if ohci_controller.IntEDs mod 16
188
if ohci_controller.IntEDs mod 16
189
.err Static endpoint descriptors must be 16-bytes aligned inside ohci_controller
189
.err Static endpoint descriptors must be 16-bytes aligned inside ohci_controller
190
end if
190
end if
191
 
191
 
192
; OHCI general transfer descriptor.
192
; OHCI general transfer descriptor.
193
; * The structure describes transfers to be performed on Control, Bulk or
193
; * The structure describes transfers to be performed on Control, Bulk or
194
;   Interrupt endpoints.
194
;   Interrupt endpoints.
195
; * The structure includes two parts, the hardware part and the software part.
195
; * The structure includes two parts, the hardware part and the software part.
196
; * The hardware part consists of first 16 bytes and corresponds to
196
; * The hardware part consists of first 16 bytes and corresponds to
197
;   the General Transfer Descriptor aka general TD from OHCI specification.
197
;   the General Transfer Descriptor aka general TD from OHCI specification.
198
; * The hardware requires 16-bytes alignment of the hardware part, so
198
; * The hardware requires 16-bytes alignment of the hardware part, so
199
;   the entire descriptor must be 16-bytes aligned. Since the allocator
199
;   the entire descriptor must be 16-bytes aligned. Since the allocator
200
;   (usb_allocate_common) allocates memory sequentially from page start
200
;   (usb_allocate_common) allocates memory sequentially from page start
201
;   (aligned on 0x1000 bytes), block size for the allocator must be
201
;   (aligned on 0x1000 bytes), block size for the allocator must be
202
;   divisible by 16; usb1_allocate_generic_td ensures this.
202
;   divisible by 16; usb1_allocate_generic_td ensures this.
203
struct ohci_gtd
203
struct ohci_gtd
204
; ------------------------------ hardware fields ------------------------------
204
; ------------------------------ hardware fields ------------------------------
205
; All addresses in this part are physical.
205
; All addresses in this part are physical.
206
Flags           dd      ?
206
Flags           dd      ?
207
; 1. Lower 18 bits (bits 0-17) are ignored and not modified by the hardware.
207
; 1. Lower 18 bits (bits 0-17) are ignored and not modified by the hardware.
208
; 2. Next bit (bit 18) is bufferRounding bit. If this bit is 0, then the last
208
; 2. Next bit (bit 18) is bufferRounding bit. If this bit is 0, then the last
209
;    data packet must exactly fill the defined data buffer. If this bit is 1,
209
;    data packet must exactly fill the defined data buffer. If this bit is 1,
210
;    then the last data packet may be smaller than the defined buffer without
210
;    then the last data packet may be smaller than the defined buffer without
211
;    causing an error condition on the TD.
211
;    causing an error condition on the TD.
212
; 3. Next 2 bits (bits 19-20) are Direction field. This field indicates the
212
; 3. Next 2 bits (bits 19-20) are Direction field. This field indicates the
213
;    direction of data flow. If the Direction field in the ED is OUT or IN,
213
;    direction of data flow. If the Direction field in the ED is OUT or IN,
214
;    this field is ignored and the direction from the ED is used instead.
214
;    this field is ignored and the direction from the ED is used instead.
215
;    Otherwise, 0 = SETUP, 1 = OUT, 2 = IN, 3 is reserved.
215
;    Otherwise, 0 = SETUP, 1 = OUT, 2 = IN, 3 is reserved.
216
; 4. Next 3 bits (bits 21-23) are DelayInterrupt field. This field contains
216
; 4. Next 3 bits (bits 21-23) are DelayInterrupt field. This field contains
217
;    the interrupt delay count for this TD. When a TD is complete, the hardware
217
;    the interrupt delay count for this TD. When a TD is complete, the hardware
218
;    may wait up to DelayInterrupt frames before generating an interrupt.
218
;    may wait up to DelayInterrupt frames before generating an interrupt.
219
;    If DelayInterrupt is 7 (maximum possible), then there is no interrupt
219
;    If DelayInterrupt is 7 (maximum possible), then there is no interrupt
220
;    associated with completion of this TD.
220
;    associated with completion of this TD.
221
; 5. Next 2 bits (bits 24-25) are DataToggle field. This field is used to
221
; 5. Next 2 bits (bits 24-25) are DataToggle field. This field is used to
222
;    generate/compare the data PID value (DATA0 or DATA1). It is updated after
222
;    generate/compare the data PID value (DATA0 or DATA1). It is updated after
223
;    each successful transmission/reception of a data packet. The bit 25
223
;    each successful transmission/reception of a data packet. The bit 25
224
;    is 0 when the data toggle value is acquired from the toggleCarry field in
224
;    is 0 when the data toggle value is acquired from the toggleCarry field in
225
;    the ED and 1 when the data toggle value is taken from the bit 24.
225
;    the ED and 1 when the data toggle value is taken from the bit 24.
226
; 6. Next 2 bits (bits 26-27) are ErrorCount field. For each transmission
226
; 6. Next 2 bits (bits 26-27) are ErrorCount field. For each transmission
227
;    error, this value is incremented. If ErrorCount is 2 and another error
227
;    error, this value is incremented. If ErrorCount is 2 and another error
228
;    occurs, the TD is retired with error. When a transaction completes without
228
;    occurs, the TD is retired with error. When a transaction completes without
229
;    error, ErrorCount is reset to 0.
229
;    error, ErrorCount is reset to 0.
230
; 7. Upper 4 bits (bits 28-31) are ConditionCode field. This field contains
230
; 7. Upper 4 bits (bits 28-31) are ConditionCode field. This field contains
231
;    the status of the last attempted transaction, one of USB_STATUS_* values.
231
;    the status of the last attempted transaction, one of USB_STATUS_* values.
232
CurBufPtr       dd      ?
232
CurBufPtr       dd      ?
233
; Physical address of the next memory location that will be accessed for
233
; Physical address of the next memory location that will be accessed for
234
; transfer to/from the endpoint. 0 means zero-length data packet or that all
234
; transfer to/from the endpoint. 0 means zero-length data packet or that all
235
; bytes have been transferred.
235
; bytes have been transferred.
236
NextTD          dd      ?
236
NextTD          dd      ?
237
; This field has different meanings depending on the status of the descriptor.
237
; This field has different meanings depending on the status of the descriptor.
238
; When the descriptor is queued for processing, but not yet processed:
238
; When the descriptor is queued for processing, but not yet processed:
239
;   Physical address of the next TD for the endpoint.
239
;   Physical address of the next TD for the endpoint.
240
; When the descriptor is processed by hardware, but not yet by software:
240
; When the descriptor is processed by hardware, but not yet by software:
241
;   Physical address of the previous processed TD.
241
;   Physical address of the previous processed TD.
242
; When the descriptor is processed by the IRQ handler, but not yet completed:
242
; When the descriptor is processed by the IRQ handler, but not yet completed:
243
;   Virtual pointer to the next processed TD.
243
;   Virtual pointer to the next processed TD.
244
BufEnd          dd      ?
244
BufEnd          dd      ?
245
; Physical address of the last byte in the buffer for this TD.
245
; Physical address of the last byte in the buffer for this TD.
246
                dd      ?       ; padding to align with uhci_gtd
246
                dd      ?       ; padding to align with uhci_gtd
247
ends
247
ends
248
 
248
 
249
; OHCI isochronous transfer descriptor.
249
; OHCI isochronous transfer descriptor.
250
; * The structure describes transfers to be performed on Isochronous endpoints.
250
; * The structure describes transfers to be performed on Isochronous endpoints.
251
; * The structure includes two parts, the hardware part and the software part.
251
; * The structure includes two parts, the hardware part and the software part.
252
; * The hardware part consists of first 32 bytes and corresponds to
252
; * The hardware part consists of first 32 bytes and corresponds to
253
;   the Isochronous Transfer Descriptor aka isochronous TD from OHCI
253
;   the Isochronous Transfer Descriptor aka isochronous TD from OHCI
254
;   specification.
254
;   specification.
255
; * The hardware requires 32-bytes alignment of the hardware part, so
255
; * The hardware requires 32-bytes alignment of the hardware part, so
256
;   the entire descriptor must be 32-bytes aligned.
256
;   the entire descriptor must be 32-bytes aligned.
257
; * The isochronous endpoints are not supported yet, so only hardware part is
257
; * The isochronous endpoints are not supported yet, so only hardware part is
258
;   defined at the moment.
258
;   defined at the moment.
259
struct ohci_itd
259
struct ohci_itd
260
StartingFrame   dw      ?
260
StartingFrame   dw      ?
261
; This field contains the low order 16 bits of the frame number in which the
261
; This field contains the low order 16 bits of the frame number in which the
262
; first data packet of the Isochronous TD is to be sent.
262
; first data packet of the Isochronous TD is to be sent.
263
Flags           dw      ?
263
Flags           dw      ?
264
; 1. Lower 5 bits (bits 0-4) are ignored and not modified by the hardware.
264
; 1. Lower 5 bits (bits 0-4) are ignored and not modified by the hardware.
265
; 2. Next 3 bits (bits 5-7) are DelayInterrupt field.
265
; 2. Next 3 bits (bits 5-7) are DelayInterrupt field.
266
; 3. Next 3 bits (bits 8-10) are FrameCount field. The TD describes
266
; 3. Next 3 bits (bits 8-10) are FrameCount field. The TD describes
267
;    FrameCount+1 data packets.
267
;    FrameCount+1 data packets.
268
; 4. Next bit (bit 11) is ignored and not modified by the hardware.
268
; 4. Next bit (bit 11) is ignored and not modified by the hardware.
269
; 5. Upper 4 bits (bits 12-15) are ConditionCode field. This field contains
269
; 5. Upper 4 bits (bits 12-15) are ConditionCode field. This field contains
270
;    the completion code, one of USB_STATUS_* values, when the TD is moved to
270
;    the completion code, one of USB_STATUS_* values, when the TD is moved to
271
;    the Done Queue.
271
;    the Done Queue.
272
BufPage0        dd      ?
272
BufPage0        dd      ?
273
; Lower 12 bits are ignored and not modified by the hardware.
273
; Lower 12 bits are ignored and not modified by the hardware.
274
; With masked 12 bits this field is the physical page containing all buffers.
274
; With masked 12 bits this field is the physical page containing all buffers.
275
NextTD          dd      ?
275
NextTD          dd      ?
276
; Physical address of the next TD in the transfer queue.
276
; Physical address of the next TD in the transfer queue.
277
BufEnd          dd      ?
277
BufEnd          dd      ?
278
; Physical address of the last byte in the buffer.
278
; Physical address of the last byte in the buffer.
279
OffsetArray     rw      8
279
OffsetArray     rw      8
280
; Initialized by software, read by hardware: Offset for packet 0..7.
280
; Initialized by software, read by hardware: Offset for packet 0..7.
281
; Used to determine size and starting address of an isochronous data packet.
281
; Used to determine size and starting address of an isochronous data packet.
282
; Written by hardware, read by software: PacketStatusWord for packet 0..7.
282
; Written by hardware, read by software: PacketStatusWord for packet 0..7.
283
; Contains completion code and, if applicable, size received for an isochronous
283
; Contains completion code and, if applicable, size received for an isochronous
284
; data packet.
284
; data packet.
285
ends
285
ends
286
 
286
 
287
; Description of OHCI-specific data and functions for
287
; Description of OHCI-specific data and functions for
288
; controller-independent code.
288
; controller-independent code.
289
; Implements the structure usb_hardware_func from hccommon.inc for OHCI.
289
; Implements the structure usb_hardware_func from hccommon.inc for OHCI.
290
iglobal
290
iglobal
291
align 4
291
align 4
292
ohci_hardware_func:
292
ohci_hardware_func:
293
        dd      'OHCI'
293
        dd      'OHCI'
294
        dd      sizeof.ohci_controller
294
        dd      sizeof.ohci_controller
295
        dd      ohci_init
295
        dd      ohci_init
296
        dd      ohci_process_deferred
296
        dd      ohci_process_deferred
297
        dd      ohci_set_device_address
297
        dd      ohci_set_device_address
298
        dd      ohci_get_device_address
298
        dd      ohci_get_device_address
299
        dd      ohci_port_disable
299
        dd      ohci_port_disable
300
        dd      ohci_new_port.reset
300
        dd      ohci_new_port.reset
301
        dd      ohci_set_endpoint_packet_size
301
        dd      ohci_set_endpoint_packet_size
302
        dd      usb1_allocate_endpoint
302
        dd      usb1_allocate_endpoint
303
        dd      usb1_free_endpoint
303
        dd      usb1_free_endpoint
304
        dd      ohci_init_pipe
304
        dd      ohci_init_pipe
305
        dd      ohci_unlink_pipe
305
        dd      ohci_unlink_pipe
306
        dd      usb1_allocate_general_td
306
        dd      usb1_allocate_general_td
307
        dd      usb1_free_general_td
307
        dd      usb1_free_general_td
308
        dd      ohci_alloc_transfer
308
        dd      ohci_alloc_transfer
309
        dd      ohci_insert_transfer
309
        dd      ohci_insert_transfer
310
        dd      ohci_new_device
310
        dd      ohci_new_device
311
endg
311
endg
312
 
312
 
313
; =============================================================================
313
; =============================================================================
314
; =================================== Code ====================================
314
; =================================== Code ====================================
315
; =============================================================================
315
; =============================================================================
316
 
316
 
317
; Controller-specific initialization function.
317
; Controller-specific initialization function.
318
; Called from usb_init_controller. Initializes the hardware and
318
; Called from usb_init_controller. Initializes the hardware and
319
; OHCI-specific parts of software structures.
319
; OHCI-specific parts of software structures.
320
; eax = pointer to ohci_controller to be initialized
320
; eax = pointer to ohci_controller to be initialized
321
; [ebp-4] = pcidevice
321
; [ebp-4] = pcidevice
322
proc ohci_init
322
proc ohci_init
323
; inherit some variables from the parent (usb_init_controller)
323
; inherit some variables from the parent (usb_init_controller)
324
.devfn   equ ebp - 4
324
.devfn   equ ebp - 4
325
.bus     equ ebp - 3
325
.bus     equ ebp - 3
326
; 1. Store pointer to ohci_controller for further use.
326
; 1. Store pointer to ohci_controller for further use.
327
        push    eax
327
        push    eax
328
        mov     edi, eax
328
        mov     edi, eax
329
; 2. Initialize hardware fields of ohci_controller.
329
; 2. Initialize hardware fields of ohci_controller.
330
; Namely, InterruptTable needs to be initialized with
330
; Namely, InterruptTable needs to be initialized with
331
; physical addresses of heads of first 32 Periodic lists.
331
; physical addresses of heads of first 32 Periodic lists.
332
; Note that all static heads fit in one page, so one call
332
; Note that all static heads fit in one page, so one call
333
; to get_pg_addr is sufficient.
333
; to get_pg_addr is sufficient.
334
if (ohci_controller.IntEDs / 0x1000) <> (ohci_controller.BulkED / 0x1000)
334
if (ohci_controller.IntEDs / 0x1000) <> (ohci_controller.BulkED / 0x1000)
335
.err assertion failed
335
.err assertion failed
336
end if
336
end if
337
if ohci_controller.IntEDs >= 0x1000
337
if ohci_controller.IntEDs >= 0x1000
338
.err assertion failed
338
.err assertion failed
339
end if
339
end if
340
        lea     esi, [eax+ohci_controller.IntEDs+32*sizeof.ohci_static_ep]
340
        lea     esi, [eax+ohci_controller.IntEDs+32*sizeof.ohci_static_ep]
341
        call    get_pg_addr
341
        call    get_pg_addr
342
        add     eax, ohci_controller.IntEDs
342
        add     eax, ohci_controller.IntEDs
343
        movi    ecx, 32
343
        movi    ecx, 32
344
        mov     edx, ecx
344
        mov     edx, ecx
345
@@:
345
@@:
346
        stosd
346
        stosd
347
        add     eax, sizeof.ohci_static_ep
347
        add     eax, sizeof.ohci_static_ep
348
        loop    @b
348
        loop    @b
349
; 3. Initialize static heads ohci_controller.IntEDs, .ControlED, .BulkED.
349
; 3. Initialize static heads ohci_controller.IntEDs, .ControlED, .BulkED.
350
; Use the loop over groups: first group consists of first 32 Periodic
350
; Use the loop over groups: first group consists of first 32 Periodic
351
; descriptors, next group consists of next 16 Periodic descriptors,
351
; descriptors, next group consists of next 16 Periodic descriptors,
352
; ..., last group consists of the last Periodic descriptor.
352
; ..., last group consists of the last Periodic descriptor.
353
; 3a. Prepare for the loop.
353
; 3a. Prepare for the loop.
354
; make edi point to start of ohci_controller.IntEDs,
354
; make edi point to start of ohci_controller.IntEDs,
355
; other registers are already set.
355
; other registers are already set.
356
; -128 fits in one byte, +128 does not fit.
356
; -128 fits in one byte, +128 does not fit.
357
        sub     edi, -128
357
        sub     edi, -128
358
; 3b. Loop over groups. On every iteration:
358
; 3b. Loop over groups. On every iteration:
359
; edx = size of group, edi = pointer to the current group,
359
; edx = size of group, edi = pointer to the current group,
360
; esi = pointer to the next group, eax = physical address of the next group.
360
; esi = pointer to the next group, eax = physical address of the next group.
361
.init_static_eds:
361
.init_static_eds:
362
; 3c. Get the size of the next group.
362
; 3c. Get the size of the next group.
363
        shr     edx, 1
363
        shr     edx, 1
364
; 3d. Exit the loop if there is no next group.
364
; 3d. Exit the loop if there is no next group.
365
        jz      .init_static_eds_done
365
        jz      .init_static_eds_done
366
; 3e. Initialize the first half of the current group.
366
; 3e. Initialize the first half of the current group.
367
; Advance edi to the second half.
367
; Advance edi to the second half.
368
        push    eax esi
368
        push    eax esi
369
        call    ohci_init_static_ep_group
369
        call    ohci_init_static_ep_group
370
        pop     esi eax
370
        pop     esi eax
371
; 3f. Initialize the second half of the current group
371
; 3f. Initialize the second half of the current group
372
; with the same values.
372
; with the same values.
373
; Advance edi to the next group, esi/eax to the next of the next group.
373
; Advance edi to the next group, esi/eax to the next of the next group.
374
        call    ohci_init_static_ep_group
374
        call    ohci_init_static_ep_group
375
        jmp     .init_static_eds
375
        jmp     .init_static_eds
376
.init_static_eds_done:
376
.init_static_eds_done:
377
; 3g. Initialize the head of the last Periodic list.
377
; 3g. Initialize the head of the last Periodic list.
378
        xor     eax, eax
378
        xor     eax, eax
379
        xor     esi, esi
379
        xor     esi, esi
380
        call    ohci_init_static_endpoint
380
        call    ohci_init_static_endpoint
381
; 3i. Initialize the heads of Control and Bulk lists.
381
; 3i. Initialize the heads of Control and Bulk lists.
382
        call    ohci_init_static_endpoint
382
        call    ohci_init_static_endpoint
383
        call    ohci_init_static_endpoint
383
        call    ohci_init_static_endpoint
384
; 4. Create a virtual memory area to talk with the controller.
384
; 4. Create a virtual memory area to talk with the controller.
385
; 4a. Enable memory & bus master access.
385
; 4a. Enable memory & bus master access.
386
        mov     ch, [.bus]
386
        mov     ch, [.bus]
387
        mov     cl, 0
387
        mov     cl, 0
388
        mov     eax, ecx
388
        mov     eax, ecx
389
        mov     bh, [.devfn]
389
        mov     bh, [.devfn]
390
        mov     bl, 4
390
        mov     bl, 4
391
        call    pci_read_reg
391
        call    pci_read_reg
392
        or      al, 6
392
        or      al, 6
393
        xchg    eax, ecx
393
        xchg    eax, ecx
394
        call    pci_write_reg
394
        call    pci_write_reg
395
; 4b. Read memory base address.
395
; 4b. Read memory base address.
396
        mov     ah, [.bus]
396
        mov     ah, [.bus]
397
        mov     al, 2
397
        mov     al, 2
398
        mov     bl, 10h
398
        mov     bl, 10h
399
        call    pci_read_reg
399
        call    pci_read_reg
400
        and     al, not 0Fh
400
        and     al, not 0Fh
401
; 4c. Create mapping for physical memory. 256 bytes are sufficient.
401
; 4c. Create mapping for physical memory. 256 bytes are sufficient.
402
        stdcall map_io_mem, eax, 100h, PG_SW+PG_NOCACHE
402
        stdcall map_io_mem, eax, 100h, PG_SW+PG_NOCACHE
403
        test    eax, eax
403
        test    eax, eax
404
        jz      .fail
404
        jz      .fail
405
        stosd   ; fill ohci_controller.MMIOBase
405
        stosd   ; fill ohci_controller.MMIOBase
406
        xchg    eax, edi
406
        xchg    eax, edi
407
; now edi = MMIOBase
407
; now edi = MMIOBase
408
; 5. Reset the controller if needed.
408
; 5. Reset the controller if needed.
409
; 5a. Check operational state.
409
; 5a. Check operational state.
410
; 0 = reset, 1 = resume, 2 = operational, 3 = suspended
410
; 0 = reset, 1 = resume, 2 = operational, 3 = suspended
411
        mov     eax, [edi+OhciControlReg]
411
        mov     eax, [edi+OhciControlReg]
412
        and     al, 3 shl 6
412
        and     al, 3 shl 6
413
        cmp     al, 2 shl 6
413
        cmp     al, 2 shl 6
414
        jz      .operational
414
        jz      .operational
415
; 5b. State is not operational, reset is needed.
415
; 5b. State is not operational, reset is needed.
416
.reset:
416
.reset:
417
; 5c. Save FmInterval register.
417
; 5c. Save FmInterval register.
418
        pushd   [edi+OhciFmIntervalReg]
418
        pushd   [edi+OhciFmIntervalReg]
419
; 5d. Issue software reset and wait up to 10ms, checking status every 1 ms.
419
; 5d. Issue software reset and wait up to 10ms, checking status every 1 ms.
420
        movi    ecx, 1
420
        movi    ecx, 1
421
        movi    edx, 10
421
        movi    edx, 10
422
        mov     [edi+OhciCommandStatusReg], ecx
422
        mov     [edi+OhciCommandStatusReg], ecx
423
@@:
423
@@:
424
        mov     esi, ecx
424
        mov     esi, ecx
425
        call    delay_ms
425
        call    delay_ms
426
        test    [edi+OhciCommandStatusReg], ecx
426
        test    [edi+OhciCommandStatusReg], ecx
427
        jz      .resetdone
427
        jz      .resetdone
428
        dec     edx
428
        dec     edx
429
        jnz     @b
429
        jnz     @b
430
        pop     eax
430
        pop     eax
431
        dbgstr 'controller reset timeout'
431
        dbgstr 'controller reset timeout'
432
        jmp     .fail_unmap
432
        jmp     .fail_unmap
433
.resetdone:
433
.resetdone:
434
; 5e. Restore FmInterval register.
434
; 5e. Restore FmInterval register.
435
        pop     eax
435
        pop     eax
436
        mov     edx, eax
436
        mov     edx, eax
437
        and     edx, 3FFFh
437
        and     edx, 3FFFh
438
        jz      .setfminterval
438
        jz      .setfminterval
439
        cmp     dx, 2EDFh       ; default value?
439
        cmp     dx, 2EDFh       ; default value?
440
        jnz     @f              ; assume that BIOS has configured the value
440
        jnz     @f              ; assume that BIOS has configured the value
441
.setfminterval:
441
.setfminterval:
442
        mov     eax, 27792EDFh  ; default value
442
        mov     eax, 27792EDFh  ; default value
443
@@:
443
@@:
444
        mov     [edi+OhciFmIntervalReg], eax
444
        mov     [edi+OhciFmIntervalReg], eax
445
; 5f. Set PeriodicStart to 90% of FmInterval.
445
; 5f. Set PeriodicStart to 90% of FmInterval.
446
        movzx   eax, ax
446
        movzx   eax, ax
447
; Two following lines are equivalent to eax = floor(eax * 0.9)
447
; Two following lines are equivalent to eax = floor(eax * 0.9)
448
; for any 0 <= eax < 1C71C71Dh, which of course is far from maximum 0FFFFh.
448
; for any 0 <= eax < 1C71C71Dh, which of course is far from maximum 0FFFFh.
449
        mov     edx, 0E6666667h
449
        mov     edx, 0E6666667h
450
        mul     edx
450
        mul     edx
451
        mov     [edi+OhciPeriodicStartReg], edx
451
        mov     [edi+OhciPeriodicStartReg], edx
452
.operational:
452
.operational:
453
; 6. Setup controller registers.
453
; 6. Setup controller registers.
454
        pop     esi     ; restore pointer to ohci_controller saved in step 1
454
        pop     esi     ; restore pointer to ohci_controller saved in step 1
455
; 6a. Physical address of HCCA.
455
; 6a. Physical address of HCCA.
456
        mov     eax, esi
456
        mov     eax, esi
457
        call    get_pg_addr
457
        call    get_pg_addr
458
        mov     [edi+OhciHCCAReg], eax
458
        mov     [edi+OhciHCCAReg], eax
459
; 6b. Transition to operational state and clear all Enable bits.
459
; 6b. Transition to operational state and clear all Enable bits.
460
        mov     cl, 2 shl 6
460
        mov     cl, 2 shl 6
461
        mov     [edi+OhciControlReg], ecx
461
        mov     [edi+OhciControlReg], ecx
462
; 6c. Physical addresses of head of Control and Bulk lists.
462
; 6c. Physical addresses of head of Control and Bulk lists.
463
if ohci_controller.BulkED >= 0x1000
463
if ohci_controller.BulkED >= 0x1000
464
.err assertion failed
464
.err assertion failed
465
end if
465
end if
466
        add     eax, ohci_controller.ControlED
466
        add     eax, ohci_controller.ControlED
467
        mov     [edi+OhciControlHeadEDReg], eax
467
        mov     [edi+OhciControlHeadEDReg], eax
468
        add     eax, ohci_controller.BulkED - ohci_controller.ControlED
468
        add     eax, ohci_controller.BulkED - ohci_controller.ControlED
469
        mov     [edi+OhciBulkHeadEDReg], eax
469
        mov     [edi+OhciBulkHeadEDReg], eax
470
; 6d. Zero Head registers: there are no active Control and Bulk descriptors yet.
470
; 6d. Zero Head registers: there are no active Control and Bulk descriptors yet.
471
        xor     eax, eax
471
        xor     eax, eax
472
;       mov     [edi+OhciPeriodCurrentEDReg], eax
472
;       mov     [edi+OhciPeriodCurrentEDReg], eax
473
        mov     [edi+OhciControlCurrentEDReg], eax
473
        mov     [edi+OhciControlCurrentEDReg], eax
474
        mov     [edi+OhciBulkCurrentEDReg], eax
474
        mov     [edi+OhciBulkCurrentEDReg], eax
475
;       mov     [edi+OhciDoneHeadReg], eax
475
;       mov     [edi+OhciDoneHeadReg], eax
476
; 6e. Enable processing of all lists with control:bulk ratio = 1:1.
476
; 6e. Enable processing of all lists with control:bulk ratio = 1:1.
477
        mov     dword [edi+OhciControlReg], 10111100b
477
        mov     dword [edi+OhciControlReg], 10111100b
478
; 7. Get number of ports.
478
; 7. Get number of ports.
479
        add     esi, sizeof.ohci_controller
479
        add     esi, sizeof.ohci_controller
480
        mov     eax, [edi+OhciRhDescriptorAReg]
480
        mov     eax, [edi+OhciRhDescriptorAReg]
481
        and     eax, 0xF
481
        and     eax, 0xF
482
        mov     [esi+usb_controller.NumPorts], eax
482
        mov     [esi+usb_controller.NumPorts], eax
483
; 8. Initialize DoneListEndPtr to point to DoneList.
483
; 8. Initialize DoneListEndPtr to point to DoneList.
484
        lea     eax, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
484
        lea     eax, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
485
        mov     [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller], eax
485
        mov     [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller], eax
486
; 9. Hook interrupt.
486
; 9. Hook interrupt.
487
        mov     ah, [.bus]
487
        mov     ah, [.bus]
488
        mov     al, 0
488
        mov     al, 0
489
        mov     bh, [.devfn]
489
        mov     bh, [.devfn]
490
        mov     bl, 3Ch
490
        mov     bl, 3Ch
491
        call    pci_read_reg
491
        call    pci_read_reg
492
; al = IRQ
492
; al = IRQ
493
        movzx   eax, al
493
        movzx   eax, al
494
        stdcall attach_int_handler, eax, ohci_irq, esi
494
        stdcall attach_int_handler, eax, ohci_irq, esi
495
; 10. Enable controller interrupt on HcDoneHead writeback and RootHubStatusChange.
495
; 10. Enable controller interrupt on HcDoneHead writeback and RootHubStatusChange.
496
        mov     dword [edi+OhciInterruptEnableReg], 80000042h
496
        mov     dword [edi+OhciInterruptEnableReg], 80000042h
497
        DEBUGF 1,'K : OHCI controller at %x:%x with %d ports initialized\n',[.bus]:2,[.devfn]:2,[esi+usb_controller.NumPorts]
497
        DEBUGF 1,'K : OHCI controller at %x:%x with %d ports initialized\n',[.bus]:2,[.devfn]:2,[esi+usb_controller.NumPorts]
498
; 11. Initialize ports of the controller.
498
; 11. Initialize ports of the controller.
499
; 11a. Initiate power up, disable all ports, clear all "changed" bits.
499
; 11a. Initiate power up, disable all ports, clear all "changed" bits.
500
        mov     dword [edi+OhciRhStatusReg], 10000h     ; SetGlobalPower
500
        mov     dword [edi+OhciRhStatusReg], 10000h     ; SetGlobalPower
501
        xor     ecx, ecx
501
        xor     ecx, ecx
502
@@:
502
@@:
503
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1F0101h  ; SetPortPower+ClearPortEnable+clear "changed" bits
503
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1F0101h  ; SetPortPower+ClearPortEnable+clear "changed" bits
504
        inc     ecx
504
        inc     ecx
505
        cmp     ecx, [esi+usb_controller.NumPorts]
505
        cmp     ecx, [esi+usb_controller.NumPorts]
506
        jb      @b
506
        jb      @b
507
; 11b. Wait for power up.
507
; 11b. Wait for power up.
508
; VirtualBox has AReg == 0, delay_ms doesn't like zero value; ignore zero delay
508
; VirtualBox has AReg == 0, delay_ms doesn't like zero value; ignore zero delay
509
        push    esi
509
        push    esi
510
        mov     esi, [edi+OhciRhDescriptorAReg]
510
        mov     esi, [edi+OhciRhDescriptorAReg]
511
        shr     esi, 24
511
        shr     esi, 24
512
        add     esi, esi
512
        add     esi, esi
513
        jz      @f
513
        jz      @f
514
        call    delay_ms
514
        call    delay_ms
515
@@:
515
@@:
516
        pop     esi
516
        pop     esi
517
; 11c. Ports are powered up; now it is ok to process connect/disconnect events.
517
; 11c. Ports are powered up; now it is ok to process connect/disconnect events.
518
        mov     [esi+ohci_controller.PoweredUp-sizeof.ohci_controller], 1
518
        mov     [esi+ohci_controller.PoweredUp-sizeof.ohci_controller], 1
519
                ; IRQ handler doesn't accept connect/disconnect events before this point
519
                ; IRQ handler doesn't accept connect/disconnect events before this point
520
; 11d. We could miss some events while waiting for powering up;
520
; 11d. We could miss some events while waiting for powering up;
521
; scan all ports manually and check for connected devices.
521
; scan all ports manually and check for connected devices.
522
        xor     ecx, ecx
522
        xor     ecx, ecx
523
.port_loop:
523
.port_loop:
524
        test    dword [edi+OhciRhPortStatusReg+ecx*4], 1
524
        test    dword [edi+OhciRhPortStatusReg+ecx*4], 1
525
        jz      .next_port
525
        jz      .next_port
526
; There is a connected device; mark the port as 'connected'
526
; There is a connected device; mark the port as 'connected'
527
; and save the connected time.
527
; and save the connected time.
528
; Note that ConnectedTime must be set before 'connected' mark,
528
; Note that ConnectedTime must be set before 'connected' mark,
529
; otherwise the code in ohci_process_deferred could use incorrect time.
529
; otherwise the code in ohci_process_deferred could use incorrect time.
530
        mov     eax, [timer_ticks]
530
        mov     eax, [timer_ticks]
531
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
531
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
532
        lock bts [esi+usb_controller.NewConnected], ecx
532
        lock bts [esi+usb_controller.NewConnected], ecx
533
.next_port:
533
.next_port:
534
        inc     ecx
534
        inc     ecx
535
        cmp     ecx, [esi+usb_controller.NumPorts]
535
        cmp     ecx, [esi+usb_controller.NumPorts]
536
        jb      .port_loop
536
        jb      .port_loop
537
; 12. Return pointer to usb_controller.
537
; 12. Return pointer to usb_controller.
538
        xchg    eax, esi
538
        xchg    eax, esi
539
        ret
539
        ret
540
.fail_unmap:
540
.fail_unmap:
541
; On error after step 4, release the virtual memory area.
541
; On error after step 4, release the virtual memory area.
542
        stdcall free_kernel_space, edi
542
        stdcall free_kernel_space, edi
543
.fail:
543
.fail:
544
; On error, free the ohci_controller structure and return zero.
544
; On error, free the ohci_controller structure and return zero.
545
; Note that the pointer was placed in the stack at step 1.
545
; Note that the pointer was placed in the stack at step 1.
546
; Note also that there can be no errors after step 8,
546
; Note also that there can be no errors after step 8,
547
; where that pointer is popped from the stack.
547
; where that pointer is popped from the stack.
548
        pop     ecx
548
        pop     ecx
549
.nothing:
549
.nothing:
550
        xor     eax, eax
550
        xor     eax, eax
551
        ret
551
        ret
552
endp
552
endp
553
 
553
 
554
; Helper procedure for step 3 of ohci_init.
554
; Helper procedure for step 3 of ohci_init.
555
; Initializes the static head of one list.
555
; Initializes the static head of one list.
556
; eax = physical address of the "next" list, esi = pointer to the "next" list,
556
; eax = physical address of the "next" list, esi = pointer to the "next" list,
557
; edi = pointer to head to initialize.
557
; edi = pointer to head to initialize.
558
; Advances edi to the next head, keeps eax/esi.
558
; Advances edi to the next head, keeps eax/esi.
559
proc ohci_init_static_endpoint
559
proc ohci_init_static_endpoint
560
        mov     byte [edi+ohci_static_ep.Flags+1], 1 shl (14 - 8)       ; sKip this endpoint
560
        mov     byte [edi+ohci_static_ep.Flags+1], 1 shl (14 - 8)       ; sKip this endpoint
561
        mov     [edi+ohci_static_ep.NextED], eax
561
        mov     [edi+ohci_static_ep.NextED], eax
562
        mov     [edi+ohci_static_ep.NextList], esi
562
        mov     [edi+ohci_static_ep.NextList], esi
563
        add     edi, ohci_static_ep.SoftwarePart
563
        add     edi, ohci_static_ep.SoftwarePart
564
        call    usb_init_static_endpoint
564
        call    usb_init_static_endpoint
565
        add     edi, sizeof.ohci_static_ep - ohci_static_ep.SoftwarePart
565
        add     edi, sizeof.ohci_static_ep - ohci_static_ep.SoftwarePart
566
        ret
566
        ret
567
endp
567
endp
568
 
568
 
569
; Helper procedure for step 3 of ohci_init.
569
; Helper procedure for step 3 of ohci_init.
570
; Initializes one half of group of static heads.
570
; Initializes one half of group of static heads.
571
; edx = size of the next group = half of size of the group,
571
; edx = size of the next group = half of size of the group,
572
; edi = pointer to the group, eax = physical address of the next group,
572
; edi = pointer to the group, eax = physical address of the next group,
573
; esi = pointer to the next group.
573
; esi = pointer to the next group.
574
; Advances eax, esi, edi to next group, keeps edx.
574
; Advances eax, esi, edi to next group, keeps edx.
575
proc ohci_init_static_ep_group
575
proc ohci_init_static_ep_group
576
        push    edx
576
        push    edx
577
@@:
577
@@:
578
        call    ohci_init_static_endpoint
578
        call    ohci_init_static_endpoint
579
        add     eax, sizeof.ohci_static_ep
579
        add     eax, sizeof.ohci_static_ep
580
        add     esi, sizeof.ohci_static_ep
580
        add     esi, sizeof.ohci_static_ep
581
        dec     edx
581
        dec     edx
582
        jnz     @b
582
        jnz     @b
583
        pop     edx
583
        pop     edx
584
        ret
584
        ret
585
endp
585
endp
586
 
586
 
587
; Controller-specific pre-initialization function: take ownership from BIOS.
587
; Controller-specific pre-initialization function: take ownership from BIOS.
588
; Some BIOSes, although not all of them, provide legacy emulation
588
; Some BIOSes, although not all of them, provide legacy emulation
589
; for USB keyboard and/or mice as PS/2-devices. In this case,
589
; for USB keyboard and/or mice as PS/2-devices. In this case,
590
; we must notify the BIOS that we don't need that emulation and know how to
590
; we must notify the BIOS that we don't need that emulation and know how to
591
; deal with USB devices.
591
; deal with USB devices.
592
proc ohci_kickoff_bios
592
proc ohci_kickoff_bios
593
; 1. Get the physical address of MMIO registers.
593
; 1. Get the physical address of MMIO registers.
594
        mov     ah, [esi+PCIDEV.bus]
594
        mov     ah, [esi+PCIDEV.bus]
595
        mov     bh, [esi+PCIDEV.devfn]
595
        mov     bh, [esi+PCIDEV.devfn]
596
        mov     al, 2
596
        mov     al, 2
597
        mov     bl, 10h
597
        mov     bl, 10h
598
        call    pci_read_reg
598
        call    pci_read_reg
599
        and     al, not 0Fh
599
        and     al, not 0Fh
600
; 2. Create mapping for physical memory. 256 bytes are sufficient.
600
; 2. Create mapping for physical memory. 256 bytes are sufficient.
601
        stdcall map_io_mem, eax, 100h, PG_SW+PG_NOCACHE
601
        stdcall map_io_mem, eax, 100h, PG_SW+PG_NOCACHE
602
        test    eax, eax
602
        test    eax, eax
603
        jz      .nothing
603
        jz      .nothing
604
; 3. Some BIOSes enable controller interrupts as a result of giving
604
; 3. Some BIOSes enable controller interrupts as a result of giving
605
; controller away. At this point the system knows nothing about how to serve
605
; controller away. At this point the system knows nothing about how to serve
606
; OHCI interrupts, so such an interrupt will send the system into an infinite
606
; OHCI interrupts, so such an interrupt will send the system into an infinite
607
; loop handling the same IRQ again and again. Thus, we need to block OHCI
607
; loop handling the same IRQ again and again. Thus, we need to block OHCI
608
; interrupts. We can't do this at the controller level until step 5,
608
; interrupts. We can't do this at the controller level until step 5,
609
; because the controller is currently owned by BIOS, so we block all hardware
609
; because the controller is currently owned by BIOS, so we block all hardware
610
; interrupts on this processor until step 5.
610
; interrupts on this processor until step 5.
611
        pushf
611
        pushf
612
        cli
612
        cli
613
; 4. Take the ownership over the controller.
613
; 4. Take the ownership over the controller.
614
; 4a. Check whether BIOS handles this controller at all.
614
; 4a. Check whether BIOS handles this controller at all.
615
        mov     edx, 100h
615
        mov     edx, 100h
616
        test    dword [eax+OhciControlReg], edx
616
        test    dword [eax+OhciControlReg], edx
617
        jz      .has_ownership
617
        jz      .has_ownership
618
; 4b. Send "take ownership" command to the BIOS.
618
; 4b. Send "take ownership" command to the BIOS.
619
; (This should generate SMI, BIOS should release its ownership in SMI handler.)
619
; (This should generate SMI, BIOS should release its ownership in SMI handler.)
620
        mov     dword [eax+OhciCommandStatusReg], 8
620
        mov     dword [eax+OhciCommandStatusReg], 8
621
; 4c. Wait for result no more than 50 ms, checking for status every 1 ms.
621
; 4c. Wait for result no more than 50 ms, checking for status every 1 ms.
622
        movi    ecx, 50
622
        movi    ecx, 50
623
@@:
623
@@:
624
        test    dword [eax+OhciControlReg], edx
624
        test    dword [eax+OhciControlReg], edx
625
        jz      .has_ownership
625
        jz      .has_ownership
626
        push    esi
626
        push    esi
627
        movi    esi, 1
627
        movi    esi, 1
628
        call    delay_ms
628
        call    delay_ms
629
        pop     esi
629
        pop     esi
630
        loop    @b
630
        loop    @b
631
        dbgstr 'warning: taking OHCI ownership from BIOS timeout'
631
        dbgstr 'warning: taking OHCI ownership from BIOS timeout'
632
.has_ownership:
632
.has_ownership:
633
; 5. Disable all controller interrupts until the system will be ready to
633
; 5. Disable all controller interrupts until the system will be ready to
634
; process them.
634
; process them.
635
        mov     dword [eax+OhciInterruptDisableReg], 0C000007Fh
635
        mov     dword [eax+OhciInterruptDisableReg], 0C000007Fh
636
; 6. Now we can unblock interrupts in the processor.
636
; 6. Now we can unblock interrupts in the processor.
637
        popf
637
        popf
638
; 7. Release memory mapping created in step 2 and return.
638
; 7. Release memory mapping created in step 2 and return.
639
        stdcall free_kernel_space, eax
639
        stdcall free_kernel_space, eax
640
.nothing:
640
.nothing:
641
        ret
641
        ret
642
endp
642
endp
643
 
643
 
644
; IRQ handler for OHCI controllers.
644
; IRQ handler for OHCI controllers.
645
ohci_irq.noint:
645
ohci_irq.noint:
646
; Not our interrupt: restore registers and return zero.
646
; Not our interrupt: restore registers and return zero.
647
        xor     eax, eax
647
        xor     eax, eax
648
        pop     edi esi ebx
648
        pop     edi esi ebx
649
        ret
649
        ret
650
 
650
 
651
proc ohci_irq
651
proc ohci_irq
652
        push    ebx esi edi     ; save used registers to be cdecl
652
        push    ebx esi edi     ; save used registers to be cdecl
653
virtual at esp
653
virtual at esp
654
                rd      3       ; saved registers
654
                rd      3       ; saved registers
655
                dd      ?       ; return address
655
                dd      ?       ; return address
656
.controller     dd      ?
656
.controller     dd      ?
657
end virtual
657
end virtual
658
; 1. ebx will hold whether some deferred processing is needed,
658
; 1. ebx will hold whether some deferred processing is needed,
659
; that cannot be done from the interrupt handler. Initialize to zero.
659
; that cannot be done from the interrupt handler. Initialize to zero.
660
        xor     ebx, ebx
660
        xor     ebx, ebx
661
; 2. Get the mask of events which should be processed.
661
; 2. Get the mask of events which should be processed.
662
        mov     esi, [.controller]
662
        mov     esi, [.controller]
663
        mov     edi, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
663
        mov     edi, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
664
        mov     eax, [edi+OhciInterruptStatusReg]
664
        mov     eax, [edi+OhciInterruptStatusReg]
665
; 3. Check whether that interrupt has been generated by our controller.
665
; 3. Check whether that interrupt has been generated by our controller.
666
; (One IRQ can be shared by several devices.)
666
; (One IRQ can be shared by several devices.)
667
        and     eax, [edi+OhciInterruptEnableReg]
667
        and     eax, [edi+OhciInterruptEnableReg]
668
        jz      .noint
668
        jz      .noint
669
; 4. Get the physical pointer to the last processed descriptor.
669
; 4. Get the physical pointer to the last processed descriptor.
670
; All processed descriptors form single-linked list from last to first
670
; All processed descriptors form single-linked list from last to first
671
; with the help of NextTD field. The list is restarted every time when
671
; with the help of NextTD field. The list is restarted every time when
672
; the controller writes to DoneHead, so grab the pointer now (before the next
672
; the controller writes to DoneHead, so grab the pointer now (before the next
673
; step) or it could be lost (the controller could write new value to DoneHead
673
; step) or it could be lost (the controller could write new value to DoneHead
674
; any time after WorkDone bit is cleared in OhciInterruptStatusReg).
674
; any time after WorkDone bit is cleared in OhciInterruptStatusReg).
675
        mov     ecx, [esi+ohci_controller.DoneHead-sizeof.ohci_controller]
675
        mov     ecx, [esi+ohci_controller.DoneHead-sizeof.ohci_controller]
676
        and     ecx, not 1
676
        and     ecx, not 1
677
; 5. Clear the events we know of.
677
; 5. Clear the events we know of.
678
; Note that this should be done before processing of events:
678
; Note that this should be done before processing of events:
679
; new events could arise while we are processing those, this way we won't lose
679
; new events could arise while we are processing those, this way we won't lose
680
; them (the controller would generate another interrupt
680
; them (the controller would generate another interrupt
681
; after completion of this one).
681
; after completion of this one).
682
        mov     [edi+OhciInterruptStatusReg], eax
682
        mov     [edi+OhciInterruptStatusReg], eax
683
; 6. Save the mask of events for further reference.
683
; 6. Save the mask of events for further reference.
684
        push    eax
684
        push    eax
685
; 7. Handle 'transfer is done' events.
685
; 7. Handle 'transfer is done' events.
686
; 7a. Test whether there are such events.
686
; 7a. Test whether there are such events.
687
        test    al, 2
687
        test    al, 2
688
        jz      .skip_donehead
688
        jz      .skip_donehead
689
; There are some 'transfer is done' events, processed descriptors are linked
689
; There are some 'transfer is done' events, processed descriptors are linked
690
; through physical addresses in the reverse order.
690
; through physical addresses in the reverse order.
691
; We can't do much in an interrupt handler, since callbacks could require
691
; We can't do much in an interrupt handler, since callbacks could require
692
; waiting for locks and that can't be done in an interrupt handler.
692
; waiting for locks and that can't be done in an interrupt handler.
693
; However, we can't also just defer all work to the USB thread, since
693
; However, we can't also just defer all work to the USB thread, since
694
; it is possible that previous lists are not yet processed and it is hard
694
; it is possible that previous lists are not yet processed and it is hard
695
; to store unlimited number of list heads. Thus, we reverse the current list,
695
; to store unlimited number of list heads. Thus, we reverse the current list,
696
; append it to end of the previous list (if there is one) and defer other
696
; append it to end of the previous list (if there is one) and defer other
697
; processing to the USB thread; this way there always is no more than one list
697
; processing to the USB thread; this way there always is no more than one list
698
; (possibly joined from several controller-reported lists).
698
; (possibly joined from several controller-reported lists).
699
; The list traversal requires converting physical addresses to virtual pointers,
699
; The list traversal requires converting physical addresses to virtual pointers,
700
; so we may as well store pointers instead of physical addresses.
700
; so we may as well store pointers instead of physical addresses.
701
; 7b. Prepare for the reversing loop.
701
; 7b. Prepare for the reversing loop.
702
        push    ebx
702
        push    ebx
703
        xor     ebx, ebx
703
        xor     ebx, ebx
704
        test    ecx, ecx
704
        test    ecx, ecx
705
        jz      .tddone
705
        jz      .tddone
706
        call    usb_td_to_virt
706
        call    usb_td_to_virt
707
        test    eax, eax
707
        test    eax, eax
708
        jz      .tddone
708
        jz      .tddone
709
        lea     edx, [eax+ohci_gtd.NextTD]
709
        lea     edx, [eax+ohci_gtd.NextTD]
710
; 7c. Reverse the list, converting physical to virtual. On every iteration:
710
; 7c. Reverse the list, converting physical to virtual. On every iteration:
711
; ecx = physical address of the current item
711
; ecx = physical address of the current item
712
; eax = virtual pointer to the current item
712
; eax = virtual pointer to the current item
713
; edx = virtual pointer to the last item.NextTD (first in the reverse list)
713
; edx = virtual pointer to the last item.NextTD (first in the reverse list)
714
; ebx = virtual pointer to the next item (previous in the reverse list)
714
; ebx = virtual pointer to the next item (previous in the reverse list)
715
.tdloop:
715
.tdloop:
716
        mov     ecx, [eax+ohci_gtd.NextTD]
716
        mov     ecx, [eax+ohci_gtd.NextTD]
717
        mov     [eax+ohci_gtd.NextTD], ebx
717
        mov     [eax+ohci_gtd.NextTD], ebx
718
        lea     ebx, [eax+sizeof.ohci_gtd]
718
        lea     ebx, [eax+sizeof.ohci_gtd]
719
        test    ecx, ecx
719
        test    ecx, ecx
720
        jz      .tddone
720
        jz      .tddone
721
        call    usb_td_to_virt
721
        call    usb_td_to_virt
722
        test    eax, eax
722
        test    eax, eax
723
        jnz     .tdloop
723
        jnz     .tdloop
724
.tddone:
724
.tddone:
725
        mov     ecx, ebx
725
        mov     ecx, ebx
726
        pop     ebx
726
        pop     ebx
727
; 7d. The list is reversed,
727
; 7d. The list is reversed,
728
; ecx = pointer to the first item, edx = pointer to the last item.NextTD.
728
; ecx = pointer to the first item, edx = pointer to the last item.NextTD.
729
; If the list is empty (unusual case), step 7 is done.
729
; If the list is empty (unusual case), step 7 is done.
730
        test    ecx, ecx
730
        test    ecx, ecx
731
        jz      .skip_donehead
731
        jz      .skip_donehead
732
; 7e. Otherwise, append this list to the end of previous one.
732
; 7e. Otherwise, append this list to the end of previous one.
733
; Note that in theory the interrupt handler and the USB thread
733
; Note that in theory the interrupt handler and the USB thread
734
; could execute in parallel.
734
; could execute in parallel.
735
.append_restart:
735
.append_restart:
736
; Atomically get DoneListEndPtr in eax and set it to edx.
736
; Atomically get DoneListEndPtr in eax and set it to edx.
737
        mov     eax, [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller]
737
        mov     eax, [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller]
738
        lock cmpxchg [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller], edx
738
        lock cmpxchg [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller], edx
739
        jnz     .append_restart
739
        jnz     .append_restart
740
; Store pointer to the new list.
740
; Store pointer to the new list.
741
; Note: we cannot perform any operations with [DoneListEndPtr]
741
; Note: we cannot perform any operations with [DoneListEndPtr]
742
; until we switch DoneListEndPtr to a new descriptor:
742
; until we switch DoneListEndPtr to a new descriptor:
743
; it is possible that after first line of .append_restart loop
743
; it is possible that after first line of .append_restart loop
744
; ohci_process_deferred obtains the control, finishes processing
744
; ohci_process_deferred obtains the control, finishes processing
745
; of the old list, sets DoneListEndPtr to address of DoneList,
745
; of the old list, sets DoneListEndPtr to address of DoneList,
746
; frees all old descriptors, so eax would point to invalid location.
746
; frees all old descriptors, so eax would point to invalid location.
747
; This way, .append_restart loop would detect that DoneListEndPtr
747
; This way, .append_restart loop would detect that DoneListEndPtr
748
; has changed, so eax needs to be re-read.
748
; has changed, so eax needs to be re-read.
749
        mov     [eax], ecx
749
        mov     [eax], ecx
750
; 7f. Notify the USB thread that there is new work.
750
; 7f. Notify the USB thread that there is new work.
751
        inc     ebx
751
        inc     ebx
752
.skip_donehead:
752
.skip_donehead:
753
; 8. Handle start-of-frame events.
753
; 8. Handle start-of-frame events.
754
; 8a. Test whether there are such events.
754
; 8a. Test whether there are such events.
755
        test    byte [esp], 4
755
        test    byte [esp], 4
756
        jz      .skip_sof
756
        jz      .skip_sof
757
; We enable SOF interrupt only when some pipes are waiting after changes.
757
; We enable SOF interrupt only when some pipes are waiting after changes.
758
        spin_lock_irqsave [esi+usb_controller.WaitSpinlock]
758
        spin_lock_irqsave [esi+usb_controller.WaitSpinlock]
759
; 8b. Make sure that there was at least one frame update
759
; 8b. Make sure that there was at least one frame update
760
; since the request. If not, wait for the next SOF.
760
; since the request. If not, wait for the next SOF.
761
        movzx   eax, [esi+ohci_controller.FrameNumber-sizeof.ohci_controller]
761
        movzx   eax, [esi+ohci_controller.FrameNumber-sizeof.ohci_controller]
762
        cmp     eax, [esi+usb_controller.StartWaitFrame]
762
        cmp     eax, [esi+usb_controller.StartWaitFrame]
763
        jz      .sof_unlock
763
        jz      .sof_unlock
764
; 8c. Copy WaitPipeRequest* to ReadyPipeHead*.
764
; 8c. Copy WaitPipeRequest* to ReadyPipeHead*.
765
        mov     eax, [esi+usb_controller.WaitPipeRequestAsync]
765
        mov     eax, [esi+usb_controller.WaitPipeRequestAsync]
766
        mov     [esi+usb_controller.ReadyPipeHeadAsync], eax
766
        mov     [esi+usb_controller.ReadyPipeHeadAsync], eax
767
        mov     eax, [esi+usb_controller.WaitPipeRequestPeriodic]
767
        mov     eax, [esi+usb_controller.WaitPipeRequestPeriodic]
768
        mov     [esi+usb_controller.ReadyPipeHeadPeriodic], eax
768
        mov     [esi+usb_controller.ReadyPipeHeadPeriodic], eax
769
; 8d. It is possible that pipe change is due to removal and
769
; 8d. It is possible that pipe change is due to removal and
770
; Control/BulkCurrentED registers still point to one of pipes to be removed.
770
; Control/BulkCurrentED registers still point to one of pipes to be removed.
771
; The code responsible for disconnect events has temporarily stopped
771
; The code responsible for disconnect events has temporarily stopped
772
; Control/Bulk processing, so it is safe to clear Control/BulkCurrentED.
772
; Control/Bulk processing, so it is safe to clear Control/BulkCurrentED.
773
; After that, restart processing.
773
; After that, restart processing.
774
        xor     edx, edx
774
        xor     edx, edx
775
        mov     [edi+OhciControlCurrentEDReg], edx
775
        mov     [edi+OhciControlCurrentEDReg], edx
776
        mov     [edi+OhciBulkCurrentEDReg], edx
776
        mov     [edi+OhciBulkCurrentEDReg], edx
777
        mov     dword [edi+OhciCommandStatusReg], 6
777
        mov     dword [edi+OhciCommandStatusReg], 6
778
        or      dword [edi+OhciControlReg], 30h
778
        or      dword [edi+OhciControlReg], 30h
779
; 8e. Disable further interrupts on SOF.
779
; 8e. Disable further interrupts on SOF.
780
; Note: OhciInterruptEnableReg/OhciInterruptDisableReg have unusual semantics.
780
; Note: OhciInterruptEnableReg/OhciInterruptDisableReg have unusual semantics.
781
        mov     dword [edi+OhciInterruptDisableReg], 4
781
        mov     dword [edi+OhciInterruptDisableReg], 4
782
; Notify the USB thread that there is new work (with pipes from ReadyPipeHead*).
782
; Notify the USB thread that there is new work (with pipes from ReadyPipeHead*).
783
        inc     ebx
783
        inc     ebx
784
.sof_unlock:
784
.sof_unlock:
785
        spin_unlock_irqrestore [esi+usb_controller.RemoveSpinlock]
785
        spin_unlock_irqrestore [esi+usb_controller.RemoveSpinlock]
786
.skip_sof:
786
.skip_sof:
787
; Handle roothub events.
787
; Handle roothub events.
788
; 9. Test whether there are such events.
788
; 9. Test whether there are such events.
789
        test    byte [esp], 40h
789
        test    byte [esp], 40h
790
        jz      .skip_roothub
790
        jz      .skip_roothub
791
; 10. Check the status of the roothub itself.
791
; 10. Check the status of the roothub itself.
792
; 10a. Global overcurrent?
792
; 10a. Global overcurrent?
793
        test    dword [edi+OhciRhStatusReg], 2
793
        test    dword [edi+OhciRhStatusReg], 2
794
        jz      @f
794
        jz      @f
795
; Note: this needs work.
795
; Note: this needs work.
796
        dbgstr 'global overcurrent'
796
        dbgstr 'global overcurrent'
797
@@:
797
@@:
798
; 10b. Clear roothub events.
798
; 10b. Clear roothub events.
799
        mov     dword [edi+OhciRhStatusReg], 80020000h
799
        mov     dword [edi+OhciRhStatusReg], 80020000h
800
; 11. Check the status of individual ports.
800
; 11. Check the status of individual ports.
801
; Look for connect/disconnect and reset events.
801
; Look for connect/disconnect and reset events.
802
; 11a. Prepare for the loop: start from port 0.
802
; 11a. Prepare for the loop: start from port 0.
803
        xor     ecx, ecx
803
        xor     ecx, ecx
804
.portloop:
804
.portloop:
805
; 11b. Get the port status and changes of it.
805
; 11b. Get the port status and changes of it.
806
; Accumulate change information.
806
; Accumulate change information.
807
; Look to "11.12.3 Port Change Information Processing" of the USB2 spec.
807
; Look to "11.12.3 Port Change Information Processing" of the USB2 spec.
808
        xor     eax, eax
808
        xor     eax, eax
809
.accloop:
809
.accloop:
810
        mov     edx, [edi+OhciRhPortStatusReg+ecx*4]
810
        mov     edx, [edi+OhciRhPortStatusReg+ecx*4]
811
        xor     ax, ax
811
        xor     ax, ax
812
        or      eax, edx
812
        or      eax, edx
813
        test    edx, 1F0000h
813
        test    edx, 1F0000h
814
        jz      .accdone
814
        jz      .accdone
815
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1F0000h
815
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1F0000h
816
        jmp     .accloop
816
        jmp     .accloop
817
.accdone:
817
.accdone:
818
; debugging output, not needed for work
818
; debugging output, not needed for work
819
;       test    eax, 1F0000h
819
;       test    eax, 1F0000h
820
;       jz      @f
820
;       jz      @f
821
;       DEBUGF 1,'K : ohci irq [%d] status of port %d is %x\n',[timer_ticks],ecx,eax
821
;       DEBUGF 1,'K : ohci irq [%d] status of port %d is %x\n',[timer_ticks],ecx,eax
822
;@@:
822
;@@:
823
; 11c. Ignore any events until all ports are powered up.
823
; 11c. Ignore any events until all ports are powered up.
824
; They will be processed by ohci_init.
824
; They will be processed by ohci_init.
825
        cmp     [esi+ohci_controller.PoweredUp-sizeof.ohci_controller], 0
825
        cmp     [esi+ohci_controller.PoweredUp-sizeof.ohci_controller], 0
826
        jz      .nextport
826
        jz      .nextport
827
; Handle changing of connection status.
827
; Handle changing of connection status.
828
        test    eax, 10000h
828
        test    eax, 10000h
829
        jz      .nocsc
829
        jz      .nocsc
830
; There was a connect or disconnect event at this port.
830
; There was a connect or disconnect event at this port.
831
; 11d. Disconnect the old device on this port, if any.
831
; 11d. Disconnect the old device on this port, if any.
832
; if the port was resetting, indicate fail and signal
832
; if the port was resetting, indicate fail and signal
833
        cmp     cl, [esi+usb_controller.ResettingPort]
833
        cmp     cl, [esi+usb_controller.ResettingPort]
834
        jnz     @f
834
        jnz     @f
835
        mov     [esi+usb_controller.ResettingStatus], -1
835
        mov     [esi+usb_controller.ResettingStatus], -1
836
        inc     ebx
836
        inc     ebx
837
@@:
837
@@:
838
        lock bts [esi+usb_controller.NewDisconnected], ecx
838
        lock bts [esi+usb_controller.NewDisconnected], ecx
839
; notify the USB thread that new work is waiting
839
; notify the USB thread that new work is waiting
840
        inc     ebx
840
        inc     ebx
841
; 11e. Change connected status. For the connection event, also
841
; 11e. Change connected status. For the connection event, also
842
; store the connection time; any further processing is permitted only
842
; store the connection time; any further processing is permitted only
843
; after USB_CONNECT_DELAY ticks.
843
; after USB_CONNECT_DELAY ticks.
844
        test    al, 1
844
        test    al, 1
845
        jz      .disconnect
845
        jz      .disconnect
846
; Note: ConnectedTime must be stored before setting the 'connected' bit,
846
; Note: ConnectedTime must be stored before setting the 'connected' bit,
847
; otherwise ohci_process_deferred could use an old time.
847
; otherwise ohci_process_deferred could use an old time.
848
        mov     eax, [timer_ticks]
848
        mov     eax, [timer_ticks]
849
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
849
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
850
        lock bts [esi+usb_controller.NewConnected], ecx
850
        lock bts [esi+usb_controller.NewConnected], ecx
851
        jmp     .nextport
851
        jmp     .nextport
852
.disconnect:
852
.disconnect:
853
        lock btr [esi+usb_controller.NewConnected], ecx
853
        lock btr [esi+usb_controller.NewConnected], ecx
854
        jmp     .nextport
854
        jmp     .nextport
855
.nocsc:
855
.nocsc:
856
; 11f. Process 'reset done' events.
856
; 11f. Process 'reset done' events.
857
        test    eax, 100000h
857
        test    eax, 100000h
858
        jz      .nextport
858
        jz      .nextport
859
        test    al, 10h
859
        test    al, 10h
860
        jnz     .nextport
860
        jnz     .nextport
861
        mov     edx, [timer_ticks]
861
        mov     edx, [timer_ticks]
862
        mov     [esi+usb_controller.ResetTime], edx
862
        mov     [esi+usb_controller.ResetTime], edx
863
        mov     [esi+usb_controller.ResettingStatus], 2
863
        mov     [esi+usb_controller.ResettingStatus], 2
864
        inc     ebx
864
        inc     ebx
865
.nextport:
865
.nextport:
866
; 11g. Continue the loop for the next port.
866
; 11g. Continue the loop for the next port.
867
        inc     ecx
867
        inc     ecx
868
        cmp     ecx, [esi+usb_controller.NumPorts]
868
        cmp     ecx, [esi+usb_controller.NumPorts]
869
        jb      .portloop
869
        jb      .portloop
870
.skip_roothub:
870
.skip_roothub:
871
; 12. Restore the stack after step 6.
871
; 12. Restore the stack after step 6.
872
        pop     eax
872
        pop     eax
873
; 13. Notify the USB thread if some deferred processing is required.
873
; 13. Notify the USB thread if some deferred processing is required.
874
        call    usb_wakeup_if_needed
874
        call    usb_wakeup_if_needed
875
; 14. Interrupt processed; return something non-zero.
875
; 14. Interrupt processed; return something non-zero.
876
        mov     al, 1
876
        mov     al, 1
877
        pop     edi esi ebx     ; restore used registers to be stdcall
877
        pop     edi esi ebx     ; restore used registers to be stdcall
878
        ret
878
        ret
879
endp
879
endp
880
 
880
 
881
; This procedure is called from usb_set_address_callback
881
; This procedure is called from usb_set_address_callback
882
; and stores USB device address in the ohci_pipe structure.
882
; and stores USB device address in the ohci_pipe structure.
883
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
883
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
884
proc ohci_set_device_address
884
proc ohci_set_device_address
885
        mov     byte [ebx+ohci_pipe.Flags-sizeof.ohci_pipe], cl
885
        mov     byte [ebx+ohci_pipe.Flags-sizeof.ohci_pipe], cl
886
; Wait until the hardware will forget the old value.
886
; Wait until the hardware will forget the old value.
887
        call    usb_subscribe_control
887
        call    usb_subscribe_control
888
        ret
888
        ret
889
endp
889
endp
890
 
890
 
891
; This procedure returns USB device address from the usb_pipe structure.
891
; This procedure returns USB device address from the usb_pipe structure.
892
; in: esi -> usb_controller, ebx -> usb_pipe
892
; in: esi -> usb_controller, ebx -> usb_pipe
893
; out: eax = endpoint address
893
; out: eax = endpoint address
894
proc ohci_get_device_address
894
proc ohci_get_device_address
895
        mov     eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
895
        mov     eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
896
        and     eax, 7Fh
896
        and     eax, 7Fh
897
        ret
897
        ret
898
endp
898
endp
899
 
899
 
900
; This procedure is called from usb_set_address_callback
900
; This procedure is called from usb_set_address_callback
901
; if the device does not accept SET_ADDRESS command and needs
901
; if the device does not accept SET_ADDRESS command and needs
902
; to be disabled at the port level.
902
; to be disabled at the port level.
903
; in: esi -> usb_controller, ecx = port
903
; in: esi -> usb_controller, ecx = port
904
proc ohci_port_disable
904
proc ohci_port_disable
905
        mov     edx, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
905
        mov     edx, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
906
        mov     dword [edx+OhciRhPortStatusReg+ecx*4], 1
906
        mov     dword [edx+OhciRhPortStatusReg+ecx*4], 1
907
        ret
907
        ret
908
endp
908
endp
909
 
909
 
910
; This procedure is called from usb_get_descr8_callback when
910
; This procedure is called from usb_get_descr8_callback when
911
; the packet size for zero endpoint becomes known and
911
; the packet size for zero endpoint becomes known and
912
; stores the packet size in ohci_pipe structure.
912
; stores the packet size in ohci_pipe structure.
913
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
913
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
914
proc ohci_set_endpoint_packet_size
914
proc ohci_set_endpoint_packet_size
915
        mov     byte [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe], cl
915
        mov     byte [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe], cl
916
; Wait until the hardware will forget the old value.
916
; Wait until the hardware will forget the old value.
917
        call    usb_subscribe_control
917
        call    usb_subscribe_control
918
        ret
918
        ret
919
endp
919
endp
920
 
920
 
921
; This procedure is called from API usb_open_pipe and processes
921
; This procedure is called from API usb_open_pipe and processes
922
; the controller-specific part of this API. See docs.
922
; the controller-specific part of this API. See docs.
923
; in: edi -> usb_pipe for target, ecx -> usb_pipe for config pipe,
923
; in: edi -> usb_pipe for target, ecx -> usb_pipe for config pipe,
924
; esi -> usb_controller, eax -> usb_gtd for the first TD,
924
; esi -> usb_controller, eax -> usb_gtd for the first TD,
925
; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type
925
; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type
926
proc ohci_init_pipe
926
proc ohci_init_pipe
927
virtual at ebp+8
927
virtual at ebp-12
-
 
928
.speed          db      ?
-
 
929
                rb      3
-
 
930
.bandwidth      dd      ?
-
 
931
.target         dd      ?
-
 
932
                rd      2
928
.config_pipe    dd      ?
933
.config_pipe    dd      ?
929
.endpoint       dd      ?
934
.endpoint       dd      ?
930
.maxpacket      dd      ?
935
.maxpacket      dd      ?
931
.type           dd      ?
936
.type           dd      ?
932
.interval       dd      ?
937
.interval       dd      ?
933
end virtual
938
end virtual
934
; 1. Initialize the queue of transfer descriptors: empty.
939
; 1. Initialize the queue of transfer descriptors: empty.
935
        sub     eax, sizeof.ohci_gtd
940
        sub     eax, sizeof.ohci_gtd
936
        call    get_phys_addr
941
        call    get_phys_addr
937
        mov     [edi+ohci_pipe.TailP-sizeof.ohci_pipe], eax
942
        mov     [edi+ohci_pipe.TailP-sizeof.ohci_pipe], eax
938
        mov     [edi+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
943
        mov     [edi+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
939
; 2. Generate ohci_pipe.Flags, see the description in ohci_pipe.
944
; 2. Generate ohci_pipe.Flags, see the description in ohci_pipe.
940
        mov     eax, [ecx+ohci_pipe.Flags-sizeof.ohci_pipe]
945
        mov     eax, [ecx+ohci_pipe.Flags-sizeof.ohci_pipe]
941
        and     eax, 0x207F     ; keep Speed bit and FunctionAddress
946
        and     eax, 0x207F     ; keep Speed bit and FunctionAddress
942
        mov     edx, [.endpoint]
947
        mov     edx, [.endpoint]
943
        and     edx, 15
948
        and     edx, 15
944
        shl     edx, 7
949
        shl     edx, 7
945
        or      eax, edx
950
        or      eax, edx
946
        mov     [edi+ohci_pipe.Flags-sizeof.ohci_pipe], eax
951
        mov     [edi+ohci_pipe.Flags-sizeof.ohci_pipe], eax
-
 
952
        bt      eax, 13
-
 
953
        setc    [.speed]
947
        mov     eax, [.maxpacket]
954
        mov     eax, [.maxpacket]
948
        mov     word [edi+ohci_pipe.Flags+2-sizeof.ohci_pipe], ax
955
        mov     word [edi+ohci_pipe.Flags+2-sizeof.ohci_pipe], ax
949
        cmp     [.type], CONTROL_PIPE
956
        cmp     [.type], CONTROL_PIPE
950
        jz      @f
957
        jz      @f
951
        test    byte [.endpoint], 80h
958
        test    byte [.endpoint], 80h
952
        setnz   al
959
        setnz   al
953
        inc     eax
960
        inc     eax
954
        shl     al, 3
961
        shl     al, 3
955
        or      byte [edi+ohci_pipe.Flags+1-sizeof.ohci_pipe], al
962
        or      byte [edi+ohci_pipe.Flags+1-sizeof.ohci_pipe], al
956
@@:
963
@@:
957
; 3. Insert the new pipe to the corresponding list of endpoints.
964
; 3. Insert the new pipe to the corresponding list of endpoints.
958
; 3a. Use Control list for control pipes, Bulk list for bulk pipes.
965
; 3a. Use Control list for control pipes, Bulk list for bulk pipes.
959
        lea     edx, [esi+ohci_controller.ControlED.SoftwarePart-sizeof.ohci_controller]
966
        lea     edx, [esi+ohci_controller.ControlED.SoftwarePart-sizeof.ohci_controller]
960
        cmp     [.type], BULK_PIPE
967
        cmp     [.type], BULK_PIPE
961
        jb      .insert ; control pipe
968
        jb      .insert ; control pipe
962
        lea     edx, [esi+ohci_controller.BulkED.SoftwarePart-sizeof.ohci_controller]
969
        lea     edx, [esi+ohci_controller.BulkED.SoftwarePart-sizeof.ohci_controller]
963
        jz      .insert ; bulk pipe
970
        jz      .insert ; bulk pipe
964
.interrupt_pipe:
971
.interrupt_pipe:
965
; 3b. For interrupt pipes, let the scheduler select the appropriate list
972
; 3b. For interrupt pipes, let the scheduler select the appropriate list
966
; based on the current bandwidth distribution and the requested bandwidth.
973
; based on the current bandwidth distribution and the requested bandwidth.
967
; This could fail if the requested bandwidth is not available;
974
; This could fail if the requested bandwidth is not available;
968
; if so, return an error.
975
; if so, return an error.
969
        lea     edx, [esi + ohci_controller.IntEDs - sizeof.ohci_controller]
976
        lea     edx, [esi + ohci_controller.IntEDs - sizeof.ohci_controller]
970
        lea     eax, [esi + ohci_controller.IntEDs + 32*sizeof.ohci_static_ep - sizeof.ohci_controller]
977
        lea     eax, [esi + ohci_controller.IntEDs + 32*sizeof.ohci_static_ep - sizeof.ohci_controller]
971
        movi    ecx, 64
978
        movi    ecx, 64
972
        call    usb1_select_interrupt_list
979
        call    usb1_select_interrupt_list
973
        test    edx, edx
980
        test    edx, edx
974
        jz      .return0
981
        jz      .return0
975
; 3c. Insert endpoint at edi to the head of list in edx.
982
; 3c. Insert endpoint at edi to the head of list in edx.
976
; Inserting to tail would work as well,
983
; Inserting to tail would work as well,
977
; but let's be consistent with other controllers.
984
; but let's be consistent with other controllers.
978
.insert:
985
.insert:
979
        mov     ecx, [edx+usb_pipe.NextVirt]
986
        mov     ecx, [edx+usb_pipe.NextVirt]
980
        mov     [edi+usb_pipe.NextVirt], ecx
987
        mov     [edi+usb_pipe.NextVirt], ecx
981
        mov     [edi+usb_pipe.PrevVirt], edx
988
        mov     [edi+usb_pipe.PrevVirt], edx
982
        mov     [ecx+usb_pipe.PrevVirt], edi
989
        mov     [ecx+usb_pipe.PrevVirt], edi
983
        mov     [edx+usb_pipe.NextVirt], edi
990
        mov     [edx+usb_pipe.NextVirt], edi
984
        mov     ecx, [edx+ohci_pipe.NextED-sizeof.ohci_pipe]
991
        mov     ecx, [edx+ohci_pipe.NextED-sizeof.ohci_pipe]
985
        mov     [edi+ohci_pipe.NextED-sizeof.ohci_pipe], ecx
992
        mov     [edi+ohci_pipe.NextED-sizeof.ohci_pipe], ecx
986
        lea     eax, [edi-sizeof.ohci_pipe]
993
        lea     eax, [edi-sizeof.ohci_pipe]
987
        call    get_phys_addr
994
        call    get_phys_addr
988
        mov     [edx+ohci_pipe.NextED-sizeof.ohci_pipe], eax
995
        mov     [edx+ohci_pipe.NextED-sizeof.ohci_pipe], eax
989
; 4. Return something non-zero.
996
; 4. Return something non-zero.
990
        ret
997
        ret
991
.return0:
998
.return0:
992
        xor     eax, eax
999
        xor     eax, eax
993
        ret
1000
        ret
994
endp
1001
endp
995
 
1002
 
996
; This function is called from ohci_process_deferred when
1003
; This function is called from ohci_process_deferred when
997
; a new device was connected at least USB_CONNECT_DELAY ticks
1004
; a new device was connected at least USB_CONNECT_DELAY ticks
998
; and therefore is ready to be configured.
1005
; and therefore is ready to be configured.
999
; ecx = port, esi -> usb_controller
1006
; ecx = port, esi -> usb_controller
1000
proc ohci_new_port
1007
proc ohci_new_port
1001
; test whether we are configuring another port
1008
; test whether we are configuring another port
1002
; if so, postpone configuring and return
1009
; if so, postpone configuring and return
1003
        bts     [esi+usb_controller.PendingPorts], ecx
1010
        bts     [esi+usb_controller.PendingPorts], ecx
1004
        cmp     [esi+usb_controller.ResettingPort], -1
1011
        cmp     [esi+usb_controller.ResettingPort], -1
1005
        jnz     .nothing
1012
        jnz     .nothing
1006
        btr     [esi+usb_controller.PendingPorts], ecx
1013
        btr     [esi+usb_controller.PendingPorts], ecx
1007
; fall through to ohci_new_port.reset
1014
; fall through to ohci_new_port.reset
1008
 
1015
 
1009
; This function is called from usb_test_pending_port.
1016
; This function is called from usb_test_pending_port.
1010
; It starts reset signalling for the port. Note that in USB first stages
1017
; It starts reset signalling for the port. Note that in USB first stages
1011
; of configuration can not be done for several ports in parallel.
1018
; of configuration can not be done for several ports in parallel.
1012
.reset:
1019
.reset:
1013
; reset port
1020
; reset port
1014
        and     [esi+usb_controller.ResettingHub], 0
1021
        and     [esi+usb_controller.ResettingHub], 0
1015
        mov     [esi+usb_controller.ResettingPort], cl
1022
        mov     [esi+usb_controller.ResettingPort], cl
1016
; Note: setting status must be the last action:
1023
; Note: setting status must be the last action:
1017
; it is possible that the device has been disconnected
1024
; it is possible that the device has been disconnected
1018
; after timeout of USB_CONNECT_DELAY but before call to ohci_new_port.
1025
; after timeout of USB_CONNECT_DELAY but before call to ohci_new_port.
1019
; In this case, ohci_irq would not set reset status to 'failed',
1026
; In this case, ohci_irq would not set reset status to 'failed',
1020
; because ohci_irq would not know that this port is to be reset.
1027
; because ohci_irq would not know that this port is to be reset.
1021
; However, the hardware would generate another interrupt
1028
; However, the hardware would generate another interrupt
1022
; in a response to reset a disconnected port, and this time
1029
; in a response to reset a disconnected port, and this time
1023
; ohci_irq knows that it needs to generate 'reset failed' event
1030
; ohci_irq knows that it needs to generate 'reset failed' event
1024
; (because ResettingPort is now filled).
1031
; (because ResettingPort is now filled).
1025
        push    edi
1032
        push    edi
1026
        mov     edi, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
1033
        mov     edi, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
1027
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 10h
1034
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 10h
1028
        pop     edi
1035
        pop     edi
1029
.nothing:
1036
.nothing:
1030
        ret
1037
        ret
1031
endp
1038
endp
1032
 
1039
 
1033
; This procedure is called from the several places in main USB code
1040
; This procedure is called from the several places in main USB code
1034
; and allocates required packets for the given transfer.
1041
; and allocates required packets for the given transfer.
1035
; ebx = pipe, other parameters are passed through the stack:
1042
; ebx = pipe, other parameters are passed through the stack:
1036
; buffer,size = data to transfer
1043
; buffer,size = data to transfer
1037
; flags = same as in usb_open_pipe: bit 0 = allow short transfer, other bits reserved
1044
; flags = same as in usb_open_pipe: bit 0 = allow short transfer, other bits reserved
1038
; td = pointer to the current end-of-queue descriptor
1045
; td = pointer to the current end-of-queue descriptor
1039
; direction =
1046
; direction =
1040
;   0000b for normal transfers,
1047
;   0000b for normal transfers,
1041
;   1000b for control SETUP transfer,
1048
;   1000b for control SETUP transfer,
1042
;   1101b for control OUT transfer,
1049
;   1101b for control OUT transfer,
1043
;   1110b for control IN transfer
1050
;   1110b for control IN transfer
1044
; returns eax = pointer to the new end-of-queue descriptor
1051
; returns eax = pointer to the new end-of-queue descriptor
1045
; (not included in the queue itself) or 0 on error
1052
; (not included in the queue itself) or 0 on error
1046
proc ohci_alloc_transfer stdcall uses edi, \
1053
proc ohci_alloc_transfer stdcall uses edi, \
1047
        buffer:dword, size:dword, flags:dword, td:dword, direction:dword
1054
        buffer:dword, size:dword, flags:dword, td:dword, direction:dword
1048
locals
1055
locals
1049
origTD          dd      ?
1056
origTD          dd      ?
1050
packetSize      dd      ?       ; must be the last variable, see usb_init_transfer
1057
packetSize      dd      ?       ; must be the last variable, see usb_init_transfer
1051
endl
1058
endl
1052
; 1. Save original value of td:
1059
; 1. Save original value of td:
1053
; it will be useful for rollback if something would fail.
1060
; it will be useful for rollback if something would fail.
1054
        mov     eax, [td]
1061
        mov     eax, [td]
1055
        mov     [origTD], eax
1062
        mov     [origTD], eax
1056
; One transfer descriptor can describe up to two pages.
1063
; One transfer descriptor can describe up to two pages.
1057
; In the worst case (when the buffer is something*1000h+0FFFh)
1064
; In the worst case (when the buffer is something*1000h+0FFFh)
1058
; this corresponds to 1001h bytes. If the requested size is
1065
; this corresponds to 1001h bytes. If the requested size is
1059
; greater, we should split the transfer into several descriptors.
1066
; greater, we should split the transfer into several descriptors.
1060
; Boundaries to split must be multiples of endpoint transfer size
1067
; Boundaries to split must be multiples of endpoint transfer size
1061
; to avoid short packets except in the end of the transfer.
1068
; to avoid short packets except in the end of the transfer.
1062
        cmp     [size], 1001h
1069
        cmp     [size], 1001h
1063
        jbe     .lastpacket
1070
        jbe     .lastpacket
1064
; 2. While the remaining data cannot fit in one packet,
1071
; 2. While the remaining data cannot fit in one packet,
1065
; allocate full-sized descriptors.
1072
; allocate full-sized descriptors.
1066
; 2a. Calculate size of one descriptor: must be a multiple of transfer size
1073
; 2a. Calculate size of one descriptor: must be a multiple of transfer size
1067
; and must be not greater than 1001h.
1074
; and must be not greater than 1001h.
1068
        movzx   ecx, word [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe]
1075
        movzx   ecx, word [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe]
1069
        mov     eax, 1001h
1076
        mov     eax, 1001h
1070
        xor     edx, edx
1077
        xor     edx, edx
1071
        mov     edi, eax
1078
        mov     edi, eax
1072
        div     ecx
1079
        div     ecx
1073
        sub     edi, edx
1080
        sub     edi, edx
1074
; 2b. Allocate in loop.
1081
; 2b. Allocate in loop.
1075
        mov     [packetSize], edi
1082
        mov     [packetSize], edi
1076
.fullpackets:
1083
.fullpackets:
1077
        call    ohci_alloc_packet
1084
        call    ohci_alloc_packet
1078
        test    eax, eax
1085
        test    eax, eax
1079
        jz      .fail
1086
        jz      .fail
1080
        mov     [td], eax
1087
        mov     [td], eax
1081
        add     [buffer], edi
1088
        add     [buffer], edi
1082
        sub     [size], edi
1089
        sub     [size], edi
1083
        cmp     [size], 1001h
1090
        cmp     [size], 1001h
1084
        ja      .fullpackets
1091
        ja      .fullpackets
1085
; 3. The remaining data can fit in one descriptor;
1092
; 3. The remaining data can fit in one descriptor;
1086
; allocate the last descriptor with size = size of remaining data.
1093
; allocate the last descriptor with size = size of remaining data.
1087
.lastpacket:
1094
.lastpacket:
1088
        mov     eax, [size]
1095
        mov     eax, [size]
1089
        mov     [packetSize], eax
1096
        mov     [packetSize], eax
1090
        call    ohci_alloc_packet
1097
        call    ohci_alloc_packet
1091
        test    eax, eax
1098
        test    eax, eax
1092
        jz      .fail
1099
        jz      .fail
1093
; 4. Enable an immediate interrupt on completion of the last packet.
1100
; 4. Enable an immediate interrupt on completion of the last packet.
1094
        and     byte [ecx+ohci_gtd.Flags+2-sizeof.ohci_gtd], not (7 shl (21-16))
1101
        and     byte [ecx+ohci_gtd.Flags+2-sizeof.ohci_gtd], not (7 shl (21-16))
1095
; 5. If a short transfer is ok for a caller, set the corresponding bit in
1102
; 5. If a short transfer is ok for a caller, set the corresponding bit in
1096
; the last descriptor, but not in others.
1103
; the last descriptor, but not in others.
1097
; Note: even if the caller says that short transfers are ok,
1104
; Note: even if the caller says that short transfers are ok,
1098
; all packets except the last one are marked as 'must be complete':
1105
; all packets except the last one are marked as 'must be complete':
1099
; if one of them will be short, the software intervention is needed
1106
; if one of them will be short, the software intervention is needed
1100
; to skip remaining packets; ohci_process_finalized_td will handle this
1107
; to skip remaining packets; ohci_process_finalized_td will handle this
1101
; transparently to the caller.
1108
; transparently to the caller.
1102
        test    [flags], 1
1109
        test    [flags], 1
1103
        jz      @f
1110
        jz      @f
1104
        or      byte [ecx+ohci_gtd.Flags+2-sizeof.ohci_gtd], 1 shl (18-16)
1111
        or      byte [ecx+ohci_gtd.Flags+2-sizeof.ohci_gtd], 1 shl (18-16)
1105
@@:
1112
@@:
1106
        ret
1113
        ret
1107
.fail:
1114
.fail:
1108
        mov     edi, ohci_hardware_func
1115
        mov     edi, ohci_hardware_func
1109
        mov     eax, [td]
1116
        mov     eax, [td]
1110
        stdcall usb_undo_tds, [origTD]
1117
        stdcall usb_undo_tds, [origTD]
1111
        xor     eax, eax
1118
        xor     eax, eax
1112
        ret
1119
        ret
1113
endp
1120
endp
1114
 
1121
 
1115
; Helper procedure for ohci_alloc_transfer.
1122
; Helper procedure for ohci_alloc_transfer.
1116
; Allocates and initializes one transfer descriptor.
1123
; Allocates and initializes one transfer descriptor.
1117
; ebx = pipe, other parameters are passed through the stack;
1124
; ebx = pipe, other parameters are passed through the stack;
1118
; fills the current last descriptor and
1125
; fills the current last descriptor and
1119
; returns eax = next descriptor (not filled).
1126
; returns eax = next descriptor (not filled).
1120
proc ohci_alloc_packet
1127
proc ohci_alloc_packet
1121
; inherit some variables from the parent ohci_alloc_transfer
1128
; inherit some variables from the parent ohci_alloc_transfer
1122
virtual at ebp-8
1129
virtual at ebp-8
1123
.origTD         dd      ?
1130
.origTD         dd      ?
1124
.packetSize     dd      ?
1131
.packetSize     dd      ?
1125
                rd      2
1132
                rd      2
1126
.buffer         dd      ?
1133
.buffer         dd      ?
1127
.transferSize   dd      ?
1134
.transferSize   dd      ?
1128
.Flags          dd      ?
1135
.Flags          dd      ?
1129
.td             dd      ?
1136
.td             dd      ?
1130
.direction      dd      ?
1137
.direction      dd      ?
1131
end virtual
1138
end virtual
1132
; 1. Allocate the next TD.
1139
; 1. Allocate the next TD.
1133
        call    usb1_allocate_general_td
1140
        call    usb1_allocate_general_td
1134
        test    eax, eax
1141
        test    eax, eax
1135
        jz      .nothing
1142
        jz      .nothing
1136
; 2. Initialize controller-independent parts of both TDs.
1143
; 2. Initialize controller-independent parts of both TDs.
1137
        push    eax
1144
        push    eax
1138
        call    usb_init_transfer
1145
        call    usb_init_transfer
1139
        pop     eax
1146
        pop     eax
1140
; 3. Save the returned value (next descriptor).
1147
; 3. Save the returned value (next descriptor).
1141
        push    eax
1148
        push    eax
1142
; 4. Store the physical address of the next descriptor.
1149
; 4. Store the physical address of the next descriptor.
1143
        sub     eax, sizeof.ohci_gtd
1150
        sub     eax, sizeof.ohci_gtd
1144
        call    get_phys_addr
1151
        call    get_phys_addr
1145
        mov     [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd], eax
1152
        mov     [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd], eax
1146
; 5. For zero-length transfers, store zero in both fields for buffer addresses.
1153
; 5. For zero-length transfers, store zero in both fields for buffer addresses.
1147
; Otherwise, fill them with real values.
1154
; Otherwise, fill them with real values.
1148
        xor     eax, eax
1155
        xor     eax, eax
1149
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1156
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1150
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1157
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1151
        cmp     [.packetSize], eax
1158
        cmp     [.packetSize], eax
1152
        jz      @f
1159
        jz      @f
1153
        mov     eax, [.buffer]
1160
        mov     eax, [.buffer]
1154
        call    get_phys_addr
1161
        call    get_phys_addr
1155
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1162
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1156
        mov     eax, [.buffer]
1163
        mov     eax, [.buffer]
1157
        add     eax, [.packetSize]
1164
        add     eax, [.packetSize]
1158
        dec     eax
1165
        dec     eax
1159
        call    get_phys_addr
1166
        call    get_phys_addr
1160
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1167
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1161
@@:
1168
@@:
1162
; 6. Generate Flags field:
1169
; 6. Generate Flags field:
1163
; - set bufferRounding (bit 18) to zero = disallow short transfers;
1170
; - set bufferRounding (bit 18) to zero = disallow short transfers;
1164
;   for the last transfer in a row, ohci_alloc_transfer would set the real value;
1171
;   for the last transfer in a row, ohci_alloc_transfer would set the real value;
1165
; - set Direction (bits 19-20) to lower 2 bits of [.direction];
1172
; - set Direction (bits 19-20) to lower 2 bits of [.direction];
1166
; - set DelayInterrupt (bits 21-23) to 7 = do not generate interrupt;
1173
; - set DelayInterrupt (bits 21-23) to 7 = do not generate interrupt;
1167
;   for the last transfer in a row, ohci_alloc_transfer would set the real value;
1174
;   for the last transfer in a row, ohci_alloc_transfer would set the real value;
1168
; - set DataToggle (bits 24-25) to next 2 bits of [.direction];
1175
; - set DataToggle (bits 24-25) to next 2 bits of [.direction];
1169
; - set ConditionCode (bits 28-31) to 1111b as a indicator that there was no
1176
; - set ConditionCode (bits 28-31) to 1111b as a indicator that there was no
1170
;   attempts to perform this transfer yet;
1177
;   attempts to perform this transfer yet;
1171
; - zero all other bits.
1178
; - zero all other bits.
1172
        mov     eax, [.direction]
1179
        mov     eax, [.direction]
1173
        mov     edx, eax
1180
        mov     edx, eax
1174
        and     eax, 3
1181
        and     eax, 3
1175
        shl     eax, 19
1182
        shl     eax, 19
1176
        and     edx, (3 shl 2)
1183
        and     edx, (3 shl 2)
1177
        shl     edx, 24 - 2
1184
        shl     edx, 24 - 2
1178
        lea     eax, [eax + edx + (7 shl 21) + (15 shl 28)]
1185
        lea     eax, [eax + edx + (7 shl 21) + (15 shl 28)]
1179
        mov     [ecx+ohci_gtd.Flags-sizeof.ohci_gtd], eax
1186
        mov     [ecx+ohci_gtd.Flags-sizeof.ohci_gtd], eax
1180
; 7. Restore the returned value saved in step 3.
1187
; 7. Restore the returned value saved in step 3.
1181
        pop     eax
1188
        pop     eax
1182
.nothing:
1189
.nothing:
1183
        ret
1190
        ret
1184
endp
1191
endp
1185
 
1192
 
1186
; This procedure is called from the several places in main USB code
1193
; This procedure is called from the several places in main USB code
1187
; and activates the transfer which was previously allocated by
1194
; and activates the transfer which was previously allocated by
1188
; ohci_alloc_transfer.
1195
; ohci_alloc_transfer.
1189
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1196
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1190
proc ohci_insert_transfer
1197
proc ohci_insert_transfer
1191
; 1. Advance the queue of transfer descriptors.
1198
; 1. Advance the queue of transfer descriptors.
1192
        mov     eax, [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1199
        mov     eax, [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1193
        mov     [ebx+ohci_pipe.TailP-sizeof.ohci_pipe], eax
1200
        mov     [ebx+ohci_pipe.TailP-sizeof.ohci_pipe], eax
1194
; 2. For control and bulk pipes, notify the controller that
1201
; 2. For control and bulk pipes, notify the controller that
1195
; there is new work in control/bulk queue respectively.
1202
; there is new work in control/bulk queue respectively.
1196
ohci_notify_new_work:
1203
ohci_notify_new_work:
1197
        mov     edx, [ebx+usb_pipe.Controller]
1204
        mov     edx, [ebx+usb_pipe.Controller]
1198
        mov     edx, [edx+ohci_controller.MMIOBase-sizeof.ohci_controller]
1205
        mov     edx, [edx+ohci_controller.MMIOBase-sizeof.ohci_controller]
1199
        cmp     [ebx+usb_pipe.Type], CONTROL_PIPE
1206
        cmp     [ebx+usb_pipe.Type], CONTROL_PIPE
1200
        jz      .control
1207
        jz      .control
1201
        cmp     [ebx+usb_pipe.Type], BULK_PIPE
1208
        cmp     [ebx+usb_pipe.Type], BULK_PIPE
1202
        jnz     .nothing
1209
        jnz     .nothing
1203
.bulk:
1210
.bulk:
1204
        mov     dword [edx+OhciCommandStatusReg], 4
1211
        mov     dword [edx+OhciCommandStatusReg], 4
1205
        jmp     .nothing
1212
        jmp     .nothing
1206
.control:
1213
.control:
1207
        mov     dword [edx+OhciCommandStatusReg], 2
1214
        mov     dword [edx+OhciCommandStatusReg], 2
1208
.nothing:
1215
.nothing:
1209
        ret
1216
        ret
1210
endp
1217
endp
1211
 
1218
 
1212
; This function is called from ohci_process_deferred when
1219
; This function is called from ohci_process_deferred when
1213
; a new device has been reset and needs to be configured.
1220
; a new device has been reset and needs to be configured.
1214
proc ohci_port_after_reset
1221
proc ohci_port_after_reset
1215
; 1. Get the status.
1222
; 1. Get the status.
1216
; If reset has been failed (device disconnected during reset),
1223
; If reset has been failed (device disconnected during reset),
1217
; continue to next device (if there is one).
1224
; continue to next device (if there is one).
1218
        xor     eax, eax
1225
        xor     eax, eax
1219
        xchg    al, [esi+usb_controller.ResettingStatus]
1226
        xchg    al, [esi+usb_controller.ResettingStatus]
1220
        test    al, al
1227
        test    al, al
1221
        js      usb_test_pending_port
1228
        js      usb_test_pending_port
1222
; If the controller has disabled the port (e.g. overcurrent),
1229
; If the controller has disabled the port (e.g. overcurrent),
1223
; continue to next device (if there is one).
1230
; continue to next device (if there is one).
1224
        movzx   ecx, [esi+usb_controller.ResettingPort]
1231
        movzx   ecx, [esi+usb_controller.ResettingPort]
1225
        mov     eax, [edi+OhciRhPortStatusReg+ecx*4]
1232
        mov     eax, [edi+OhciRhPortStatusReg+ecx*4]
1226
        test    al, 2
1233
        test    al, 2
1227
        jnz     @f
1234
        jnz     @f
1228
        DEBUGF 1,'K : USB port disabled after reset, status=%x\n',eax
1235
        DEBUGF 1,'K : USB port disabled after reset, status=%x\n',eax
1229
        jmp     usb_test_pending_port
1236
        jmp     usb_test_pending_port
1230
@@:
1237
@@:
1231
        push    ecx
1238
        push    ecx
1232
; 2. Get LowSpeed bit to bit 0 of eax and call the worker procedure
1239
; 2. Get LowSpeed bit to bit 0 of eax and call the worker procedure
1233
; to notify the protocol layer about new OHCI device.
1240
; to notify the protocol layer about new OHCI device.
1234
        mov     eax, [edi+OhciRhPortStatusReg+ecx*4]
1241
        mov     eax, [edi+OhciRhPortStatusReg+ecx*4]
1235
        DEBUGF 1,'K : port_after_reset [%d] status of port %d is %x\n',[timer_ticks],ecx,eax
1242
        DEBUGF 1,'K : port_after_reset [%d] status of port %d is %x\n',[timer_ticks],ecx,eax
1236
        shr     eax, 9
1243
        shr     eax, 9
1237
        call    ohci_new_device
1244
        call    ohci_new_device
1238
        pop     ecx
1245
        pop     ecx
1239
; 3. If something at the protocol layer has failed
1246
; 3. If something at the protocol layer has failed
1240
; (no memory, no bus address), disable the port and stop the initialization.
1247
; (no memory, no bus address), disable the port and stop the initialization.
1241
        test    eax, eax
1248
        test    eax, eax
1242
        jnz     .nothing
1249
        jnz     .nothing
1243
.disable_exit:
1250
.disable_exit:
1244
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1
1251
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1
1245
        jmp     usb_test_pending_port
1252
        jmp     usb_test_pending_port
1246
.nothing:
1253
.nothing:
1247
        ret
1254
        ret
1248
endp
1255
endp
1249
 
1256
 
1250
; This procedure is called from uhci_port_init and from hub support code
1257
; This procedure is called from uhci_port_init and from hub support code
1251
; when a new device is connected and has been reset.
1258
; when a new device is connected and has been reset.
1252
; It calls usb_new_device at the protocol layer with correct parameters.
1259
; It calls usb_new_device at the protocol layer with correct parameters.
1253
; in: esi -> usb_controller, eax = speed;
1260
; in: esi -> usb_controller, eax = speed;
1254
; OHCI is USB1 device, so only low bit of eax (LowSpeed) is used.
1261
; OHCI is USB1 device, so only low bit of eax (LowSpeed) is used.
1255
proc ohci_new_device
1262
proc ohci_new_device
1256
; 1. Clear all bits of speed except bit 0.
1263
; 1. Clear all bits of speed except bit 0.
1257
        and     eax, 1
1264
        and     eax, 1
1258
; 2. Store the speed for the protocol layer.
1265
; 2. Store the speed for the protocol layer.
1259
        mov     [esi+usb_controller.ResettingSpeed], al
1266
        mov     [esi+usb_controller.ResettingSpeed], al
1260
; 3. Create pseudo-pipe in the stack.
1267
; 3. Create pseudo-pipe in the stack.
1261
; See ohci_init_pipe: only .Controller and .Flags fields are used.
1268
; See ohci_init_pipe: only .Controller and .Flags fields are used.
1262
        shl     eax, 13
1269
        shl     eax, 13
1263
        push    esi     ; .Controller
1270
        push    esi     ; .Controller
1264
        mov     ecx, esp
1271
        mov     ecx, esp
1265
        sub     esp, 12 ; ignored fields
1272
        sub     esp, 12 ; ignored fields
1266
        push    eax     ; .Flags
1273
        push    eax     ; .Flags
1267
; 4. Notify the protocol layer.
1274
; 4. Notify the protocol layer.
1268
        call    usb_new_device
1275
        call    usb_new_device
1269
; 5. Cleanup the stack after step 3 and return.
1276
; 5. Cleanup the stack after step 3 and return.
1270
        add     esp, 20
1277
        add     esp, 20
1271
        ret
1278
        ret
1272
endp
1279
endp
1273
 
1280
 
1274
; This procedure is called in the USB thread from usb_thread_proc,
1281
; This procedure is called in the USB thread from usb_thread_proc,
1275
; processes regular actions and those actions which can't be safely done
1282
; processes regular actions and those actions which can't be safely done
1276
; from interrupt handler.
1283
; from interrupt handler.
1277
; Returns maximal time delta before the next call.
1284
; Returns maximal time delta before the next call.
1278
proc ohci_process_deferred
1285
proc ohci_process_deferred
1279
        push    ebx edi         ; save used registers to be stdcall
1286
        push    ebx edi         ; save used registers to be stdcall
1280
; 1. Initialize the return value.
1287
; 1. Initialize the return value.
1281
        push    -1
1288
        push    -1
1282
; 2. Process disconnect events.
1289
; 2. Process disconnect events.
1283
        call    usb_disconnect_stage2
1290
        call    usb_disconnect_stage2
1284
; 3. Check for connected devices.
1291
; 3. Check for connected devices.
1285
; If there is a connected device which was connected less than
1292
; If there is a connected device which was connected less than
1286
; USB_CONNECT_DELAY ticks ago, plan to wake up when the delay will be over.
1293
; USB_CONNECT_DELAY ticks ago, plan to wake up when the delay will be over.
1287
; Otherwise, call ohci_new_port.
1294
; Otherwise, call ohci_new_port.
1288
        mov     edi, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
1295
        mov     edi, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
1289
        xor     ecx, ecx
1296
        xor     ecx, ecx
1290
        cmp     [esi+usb_controller.NewConnected], ecx
1297
        cmp     [esi+usb_controller.NewConnected], ecx
1291
        jz      .skip_newconnected
1298
        jz      .skip_newconnected
1292
.portloop:
1299
.portloop:
1293
        bt      [esi+usb_controller.NewConnected], ecx
1300
        bt      [esi+usb_controller.NewConnected], ecx
1294
        jnc     .noconnect
1301
        jnc     .noconnect
1295
        mov     eax, [timer_ticks]
1302
        mov     eax, [timer_ticks]
1296
        sub     eax, [esi+usb_controller.ConnectedTime+ecx*4]
1303
        sub     eax, [esi+usb_controller.ConnectedTime+ecx*4]
1297
        sub     eax, USB_CONNECT_DELAY
1304
        sub     eax, USB_CONNECT_DELAY
1298
        jge     .connected
1305
        jge     .connected
1299
        neg     eax
1306
        neg     eax
1300
        cmp     [esp], eax
1307
        cmp     [esp], eax
1301
        jb      .nextport
1308
        jb      .nextport
1302
        mov     [esp], eax
1309
        mov     [esp], eax
1303
        jmp     .nextport
1310
        jmp     .nextport
1304
.connected:
1311
.connected:
1305
        lock btr [esi+usb_controller.NewConnected], ecx
1312
        lock btr [esi+usb_controller.NewConnected], ecx
1306
        jnc     .nextport
1313
        jnc     .nextport
1307
        call    ohci_new_port
1314
        call    ohci_new_port
1308
.noconnect:
1315
.noconnect:
1309
.nextport:
1316
.nextport:
1310
        inc     ecx
1317
        inc     ecx
1311
        cmp     ecx, [esi+usb_controller.NumPorts]
1318
        cmp     ecx, [esi+usb_controller.NumPorts]
1312
        jb      .portloop
1319
        jb      .portloop
1313
.skip_newconnected:
1320
.skip_newconnected:
1314
; 4. Check for end of reset signalling. If so, call ohci_port_after_reset.
1321
; 4. Check for end of reset signalling. If so, call ohci_port_after_reset.
1315
        cmp     [esi+usb_controller.ResettingStatus], 2
1322
        cmp     [esi+usb_controller.ResettingStatus], 2
1316
        jnz     .no_reset_recovery
1323
        jnz     .no_reset_recovery
1317
        mov     eax, [timer_ticks]
1324
        mov     eax, [timer_ticks]
1318
        sub     eax, [esi+usb_controller.ResetTime]
1325
        sub     eax, [esi+usb_controller.ResetTime]
1319
        sub     eax, USB_RESET_RECOVERY_TIME
1326
        sub     eax, USB_RESET_RECOVERY_TIME
1320
        jge     .reset_done
1327
        jge     .reset_done
1321
        neg     eax
1328
        neg     eax
1322
        cmp     [esp], eax
1329
        cmp     [esp], eax
1323
        jb      .skip_roothub
1330
        jb      .skip_roothub
1324
        mov     [esp], eax
1331
        mov     [esp], eax
1325
        jmp     .skip_roothub
1332
        jmp     .skip_roothub
1326
.no_reset_recovery:
1333
.no_reset_recovery:
1327
        cmp     [esi+usb_controller.ResettingStatus], 0
1334
        cmp     [esi+usb_controller.ResettingStatus], 0
1328
        jz      .skip_roothub
1335
        jz      .skip_roothub
1329
.reset_done:
1336
.reset_done:
1330
        call    ohci_port_after_reset
1337
        call    ohci_port_after_reset
1331
.skip_roothub:
1338
.skip_roothub:
1332
; 5. Finalize transfers processed by hardware.
1339
; 5. Finalize transfers processed by hardware.
1333
; It is better to perform this step after processing disconnect events,
1340
; It is better to perform this step after processing disconnect events,
1334
; although not strictly obligatory. This way, an active transfer aborted
1341
; although not strictly obligatory. This way, an active transfer aborted
1335
; due to disconnect would be handled with more specific USB_STATUS_CLOSED,
1342
; due to disconnect would be handled with more specific USB_STATUS_CLOSED,
1336
; not USB_STATUS_NORESPONSE.
1343
; not USB_STATUS_NORESPONSE.
1337
; Loop over all items in DoneList, call ohci_process_finalized_td for each.
1344
; Loop over all items in DoneList, call ohci_process_finalized_td for each.
1338
        xor     ebx, ebx
1345
        xor     ebx, ebx
1339
        xchg    ebx, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
1346
        xchg    ebx, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
1340
.tdloop:
1347
.tdloop:
1341
        test    ebx, ebx
1348
        test    ebx, ebx
1342
        jz      .tddone
1349
        jz      .tddone
1343
        call    ohci_process_finalized_td
1350
        call    ohci_process_finalized_td
1344
        jmp     .tdloop
1351
        jmp     .tdloop
1345
.tddone:
1352
.tddone:
1346
; 6. Process wait-done notifications, test for new wait requests.
1353
; 6. Process wait-done notifications, test for new wait requests.
1347
; Note: that must be done after steps 2 and 5 which could create new requests.
1354
; Note: that must be done after steps 2 and 5 which could create new requests.
1348
; 6a. Call the worker function from main USB code.
1355
; 6a. Call the worker function from main USB code.
1349
        call    usb_process_wait_lists
1356
        call    usb_process_wait_lists
1350
; 6b. If no new requests, skip the rest of this step.
1357
; 6b. If no new requests, skip the rest of this step.
1351
        test    eax, eax
1358
        test    eax, eax
1352
        jz      @f
1359
        jz      @f
1353
; 6c. OHCI is not allowed to cache anything; we don't know what is
1360
; 6c. OHCI is not allowed to cache anything; we don't know what is
1354
; processed right now, but we can be sure that the controller will not
1361
; processed right now, but we can be sure that the controller will not
1355
; use any removed structure starting from the next frame.
1362
; use any removed structure starting from the next frame.
1356
; Schedule SOF event.
1363
; Schedule SOF event.
1357
        spin_lock_irq [esi+usb_controller.RemoveSpinlock]
1364
        spin_lock_irq [esi+usb_controller.RemoveSpinlock]
1358
        mov     eax, [esi+usb_controller.WaitPipeListAsync]
1365
        mov     eax, [esi+usb_controller.WaitPipeListAsync]
1359
        mov     [esi+usb_controller.WaitPipeRequestAsync], eax
1366
        mov     [esi+usb_controller.WaitPipeRequestAsync], eax
1360
        mov     eax, [esi+usb_controller.WaitPipeListPeriodic]
1367
        mov     eax, [esi+usb_controller.WaitPipeListPeriodic]
1361
        mov     [esi+usb_controller.WaitPipeRequestPeriodic], eax
1368
        mov     [esi+usb_controller.WaitPipeRequestPeriodic], eax
1362
; temporarily stop bulk and interrupt processing;
1369
; temporarily stop bulk and interrupt processing;
1363
; this is required for handler of SOF event
1370
; this is required for handler of SOF event
1364
        and     dword [edi+OhciControlReg], not 30h
1371
        and     dword [edi+OhciControlReg], not 30h
1365
; remember the frame number when processing has been stopped
1372
; remember the frame number when processing has been stopped
1366
; (needs to be done after stopping)
1373
; (needs to be done after stopping)
1367
        movzx   eax, [esi+ohci_controller.FrameNumber-sizeof.ohci_controller]
1374
        movzx   eax, [esi+ohci_controller.FrameNumber-sizeof.ohci_controller]
1368
        mov     [esi+usb_controller.StartWaitFrame], eax
1375
        mov     [esi+usb_controller.StartWaitFrame], eax
1369
; make sure that the next SOF will happen after the request
1376
; make sure that the next SOF will happen after the request
1370
        mov     dword [edi+OhciInterruptStatusReg], 4
1377
        mov     dword [edi+OhciInterruptStatusReg], 4
1371
; enable interrupt on SOF
1378
; enable interrupt on SOF
1372
; Note: OhciInterruptEnableReg/OhciInterruptDisableReg have unusual semantics,
1379
; Note: OhciInterruptEnableReg/OhciInterruptDisableReg have unusual semantics,
1373
; so there should be 'mov' here, not 'or'
1380
; so there should be 'mov' here, not 'or'
1374
        mov     dword [edi+OhciInterruptEnableReg], 4
1381
        mov     dword [edi+OhciInterruptEnableReg], 4
1375
        spin_unlock_irq [esi+usb_controller.RemoveSpinlock]
1382
        spin_unlock_irq [esi+usb_controller.RemoveSpinlock]
1376
@@:
1383
@@:
1377
; 7. Restore the return value and return.
1384
; 7. Restore the return value and return.
1378
        pop     eax
1385
        pop     eax
1379
        pop     edi ebx         ; restore used registers to be stdcall
1386
        pop     edi ebx         ; restore used registers to be stdcall
1380
        ret
1387
        ret
1381
endp
1388
endp
1382
 
1389
 
1383
; Helper procedure for ohci_process_deferred. Processes one completed TD.
1390
; Helper procedure for ohci_process_deferred. Processes one completed TD.
1384
; in: esi -> usb_controller, ebx -> usb_gtd, out: ebx -> next usb_gtd.
1391
; in: esi -> usb_controller, ebx -> usb_gtd, out: ebx -> next usb_gtd.
1385
proc ohci_process_finalized_td
1392
proc ohci_process_finalized_td
1386
;       DEBUGF 1,'K : processing %x\n',ebx
1393
;       DEBUGF 1,'K : processing %x\n',ebx
1387
; 1. Check whether the pipe has been closed, either due to API call or due to
1394
; 1. Check whether the pipe has been closed, either due to API call or due to
1388
; disconnect; if so, the callback will be called by usb_pipe_closed with
1395
; disconnect; if so, the callback will be called by usb_pipe_closed with
1389
; correct status, so go to step 6 with ebx = 0 (do not free the TD).
1396
; correct status, so go to step 6 with ebx = 0 (do not free the TD).
1390
        mov     edx, [ebx+usb_gtd.Pipe]
1397
        mov     edx, [ebx+usb_gtd.Pipe]
1391
        test    [edx+usb_pipe.Flags], USB_FLAG_CLOSED
1398
        test    [edx+usb_pipe.Flags], USB_FLAG_CLOSED
1392
        jz      @f
1399
        jz      @f
1393
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1400
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1394
        xor     ebx, ebx
1401
        xor     ebx, ebx
1395
        jmp     .next_td2
1402
        jmp     .next_td2
1396
@@:
1403
@@:
1397
; 2. Remove the descriptor from the descriptors queue.
1404
; 2. Remove the descriptor from the descriptors queue.
1398
        call    usb_unlink_td
1405
        call    usb_unlink_td
1399
; 3. Get number of bytes that remain to be transferred.
1406
; 3. Get number of bytes that remain to be transferred.
1400
; If CurBufPtr is zero, everything was transferred.
1407
; If CurBufPtr is zero, everything was transferred.
1401
        xor     edx, edx
1408
        xor     edx, edx
1402
        cmp     [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], edx
1409
        cmp     [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], edx
1403
        jz      .gotlen
1410
        jz      .gotlen
1404
; Otherwise, the remaining length is
1411
; Otherwise, the remaining length is
1405
; (BufEnd and 0xFFF) - (CurBufPtr and 0xFFF) + 1,
1412
; (BufEnd and 0xFFF) - (CurBufPtr and 0xFFF) + 1,
1406
; plus 0x1000 if BufEnd and CurBufPtr are in different pages.
1413
; plus 0x1000 if BufEnd and CurBufPtr are in different pages.
1407
        mov     edx, [ebx+ohci_gtd.BufEnd-sizeof.ohci_gtd]
1414
        mov     edx, [ebx+ohci_gtd.BufEnd-sizeof.ohci_gtd]
1408
        mov     eax, [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd]
1415
        mov     eax, [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd]
1409
        mov     ecx, edx
1416
        mov     ecx, edx
1410
        and     edx, 0xFFF
1417
        and     edx, 0xFFF
1411
        inc     edx
1418
        inc     edx
1412
        xor     ecx, eax
1419
        xor     ecx, eax
1413
        and     ecx, -0x1000
1420
        and     ecx, -0x1000
1414
        jz      @f
1421
        jz      @f
1415
        add     edx, 0x1000
1422
        add     edx, 0x1000
1416
@@:
1423
@@:
1417
        and     eax, 0xFFF
1424
        and     eax, 0xFFF
1418
        sub     edx, eax
1425
        sub     edx, eax
1419
.gotlen:
1426
.gotlen:
1420
; The actual length is Length - (remaining length).
1427
; The actual length is Length - (remaining length).
1421
        sub     edx, [ebx+usb_gtd.Length]
1428
        sub     edx, [ebx+usb_gtd.Length]
1422
        neg     edx
1429
        neg     edx
1423
; 4. Check for error. If so, go to 7.
1430
; 4. Check for error. If so, go to 7.
1424
        push    ebx
1431
        push    ebx
1425
        mov     eax, [ebx+ohci_gtd.Flags-sizeof.ohci_gtd]
1432
        mov     eax, [ebx+ohci_gtd.Flags-sizeof.ohci_gtd]
1426
        shr     eax, 28
1433
        shr     eax, 28
1427
        jnz     .error
1434
        jnz     .error
1428
.notify:
1435
.notify:
1429
; 5. Successful completion.
1436
; 5. Successful completion.
1430
; 5a. Check whether this descriptor has an associated callback.
1437
; 5a. Check whether this descriptor has an associated callback.
1431
        mov     ecx, [ebx+usb_gtd.Callback]
1438
        mov     ecx, [ebx+usb_gtd.Callback]
1432
        test    ecx, ecx
1439
        test    ecx, ecx
1433
        jz      .ok_nocallback
1440
        jz      .ok_nocallback
1434
; 5b. If so, call the callback.
1441
; 5b. If so, call the callback.
1435
        stdcall_verify ecx, [ebx+usb_gtd.Pipe], eax, \
1442
        stdcall_verify ecx, [ebx+usb_gtd.Pipe], eax, \
1436
                [ebx+usb_gtd.Buffer], edx, [ebx+usb_gtd.UserData]
1443
                [ebx+usb_gtd.Buffer], edx, [ebx+usb_gtd.UserData]
1437
        jmp     .next_td
1444
        jmp     .next_td
1438
.ok_nocallback:
1445
.ok_nocallback:
1439
; 5c. Otherwise, add length of the current descriptor to the next descriptor.
1446
; 5c. Otherwise, add length of the current descriptor to the next descriptor.
1440
        mov     eax, [ebx+usb_gtd.NextVirt]
1447
        mov     eax, [ebx+usb_gtd.NextVirt]
1441
        add     [eax+usb_gtd.Length], edx
1448
        add     [eax+usb_gtd.Length], edx
1442
.next_td:
1449
.next_td:
1443
; 6. Free the current descriptor and advance to the next item.
1450
; 6. Free the current descriptor and advance to the next item.
1444
; If the current item is the last in the list,
1451
; If the current item is the last in the list,
1445
; set DoneListEndPtr to pointer to DoneList.
1452
; set DoneListEndPtr to pointer to DoneList.
1446
        cmp     ebx, [esp]
1453
        cmp     ebx, [esp]
1447
        jz      @f
1454
        jz      @f
1448
        stdcall usb1_free_general_td, ebx
1455
        stdcall usb1_free_general_td, ebx
1449
@@:
1456
@@:
1450
        pop     ebx
1457
        pop     ebx
1451
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1458
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1452
.next_td2:
1459
.next_td2:
1453
        push    ebx
1460
        push    ebx
1454
        mov     ebx, eax
1461
        mov     ebx, eax
1455
        lea     edx, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
1462
        lea     edx, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
1456
        xor     ecx, ecx        ; no next item
1463
        xor     ecx, ecx        ; no next item
1457
        lock cmpxchg [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller], edx
1464
        lock cmpxchg [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller], edx
1458
        jz      .last
1465
        jz      .last
1459
; The current item is not the last.
1466
; The current item is not the last.
1460
; It is possible, although very rare, that ohci_irq has already advanced
1467
; It is possible, although very rare, that ohci_irq has already advanced
1461
; DoneListEndPtr, but not yet written NextTD. Wait until NextTD is nonzero.
1468
; DoneListEndPtr, but not yet written NextTD. Wait until NextTD is nonzero.
1462
@@:
1469
@@:
1463
        mov     ecx, [ebx]
1470
        mov     ecx, [ebx]
1464
        test    ecx, ecx
1471
        test    ecx, ecx
1465
        jz      @b
1472
        jz      @b
1466
.last:
1473
.last:
1467
        pop     ebx
1474
        pop     ebx
1468
; ecx = the next item
1475
; ecx = the next item
1469
        push    ecx
1476
        push    ecx
1470
; Free the current item, set ebx to the next item, continue to 5a.
1477
; Free the current item, set ebx to the next item, continue to 5a.
1471
        test    ebx, ebx
1478
        test    ebx, ebx
1472
        jz      @f
1479
        jz      @f
1473
        stdcall usb1_free_general_td, ebx
1480
        stdcall usb1_free_general_td, ebx
1474
@@:
1481
@@:
1475
        pop     ebx
1482
        pop     ebx
1476
        ret
1483
        ret
1477
.error:
1484
.error:
1478
; 7. There was an error while processing this descriptor.
1485
; 7. There was an error while processing this descriptor.
1479
; The hardware has stopped processing the queue.
1486
; The hardware has stopped processing the queue.
1480
; 7a. Save status and length.
1487
; 7a. Save status and length.
1481
        push    eax
1488
        push    eax
1482
        push    edx
1489
        push    edx
1483
;       DEBUGF 1,'K : TD failed:\n'
1490
;       DEBUGF 1,'K : TD failed:\n'
1484
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd],[ebx-sizeof.ohci_gtd+4],[ebx-sizeof.ohci_gtd+8],[ebx-sizeof.ohci_gtd+12]
1491
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd],[ebx-sizeof.ohci_gtd+4],[ebx-sizeof.ohci_gtd+8],[ebx-sizeof.ohci_gtd+12]
1485
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd+16],[ebx-sizeof.ohci_gtd+20],[ebx-sizeof.ohci_gtd+24],[ebx-sizeof.ohci_gtd+28]
1492
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd+16],[ebx-sizeof.ohci_gtd+20],[ebx-sizeof.ohci_gtd+24],[ebx-sizeof.ohci_gtd+28]
1486
;       mov     eax, [ebx+usb_gtd.Pipe]
1493
;       mov     eax, [ebx+usb_gtd.Pipe]
1487
;       DEBUGF 1,'K : pipe: %x %x %x %x\n',[eax-sizeof.ohci_pipe],[eax-sizeof.ohci_pipe+4],[eax-sizeof.ohci_pipe+8],[eax-sizeof.ohci_pipe+12]
1494
;       DEBUGF 1,'K : pipe: %x %x %x %x\n',[eax-sizeof.ohci_pipe],[eax-sizeof.ohci_pipe+4],[eax-sizeof.ohci_pipe+8],[eax-sizeof.ohci_pipe+12]
1488
; 7b. Traverse the list of descriptors looking for the final packet
1495
; 7b. Traverse the list of descriptors looking for the final packet
1489
; for this transfer.
1496
; for this transfer.
1490
; Free and unlink non-final descriptors, except the current one.
1497
; Free and unlink non-final descriptors, except the current one.
1491
; Final descriptor will be freed in step 6.
1498
; Final descriptor will be freed in step 6.
1492
        call    usb_is_final_packet
1499
        call    usb_is_final_packet
1493
        jnc     .found_final
1500
        jnc     .found_final
1494
        mov     ebx, [ebx+usb_gtd.NextVirt]
1501
        mov     ebx, [ebx+usb_gtd.NextVirt]
1495
virtual at esp
1502
virtual at esp
1496
.length         dd      ?
1503
.length         dd      ?
1497
.error_code     dd      ?
1504
.error_code     dd      ?
1498
.current_item   dd      ?
1505
.current_item   dd      ?
1499
end virtual
1506
end virtual
1500
.look_final:
1507
.look_final:
1501
        call    usb_unlink_td
1508
        call    usb_unlink_td
1502
        call    usb_is_final_packet
1509
        call    usb_is_final_packet
1503
        jnc     .found_final
1510
        jnc     .found_final
1504
        push    [ebx+usb_gtd.NextVirt]
1511
        push    [ebx+usb_gtd.NextVirt]
1505
        stdcall usb1_free_general_td, ebx
1512
        stdcall usb1_free_general_td, ebx
1506
        pop     ebx
1513
        pop     ebx
1507
        jmp     .look_final
1514
        jmp     .look_final
1508
.found_final:
1515
.found_final:
1509
; 7c. If error code is USB_STATUS_UNDERRUN and the last TD allows short packets,
1516
; 7c. If error code is USB_STATUS_UNDERRUN and the last TD allows short packets,
1510
; it is not an error.
1517
; it is not an error.
1511
; Note: all TDs except the last one in any transfer stage are marked
1518
; Note: all TDs except the last one in any transfer stage are marked
1512
; as short-packet-is-error to stop controller from further processing
1519
; as short-packet-is-error to stop controller from further processing
1513
; of that stage; we need to restart processing from a TD following the last.
1520
; of that stage; we need to restart processing from a TD following the last.
1514
; After that, go to step 5 with eax = 0 (no error).
1521
; After that, go to step 5 with eax = 0 (no error).
1515
        cmp     dword [.error_code], USB_STATUS_UNDERRUN
1522
        cmp     dword [.error_code], USB_STATUS_UNDERRUN
1516
        jnz     .no_underrun
1523
        jnz     .no_underrun
1517
        test    byte [ebx+ohci_gtd.Flags+2-sizeof.ohci_gtd], 1 shl (18-16)
1524
        test    byte [ebx+ohci_gtd.Flags+2-sizeof.ohci_gtd], 1 shl (18-16)
1518
        jz      .no_underrun
1525
        jz      .no_underrun
1519
        and     dword [.error_code], 0
1526
        and     dword [.error_code], 0
1520
        mov     ecx, [ebx+usb_gtd.Pipe]
1527
        mov     ecx, [ebx+usb_gtd.Pipe]
1521
        mov     edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
1528
        mov     edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
1522
        and     edx, 2
1529
        and     edx, 2
1523
.advance_queue:
1530
.advance_queue:
1524
        mov     eax, [ebx+usb_gtd.NextVirt]
1531
        mov     eax, [ebx+usb_gtd.NextVirt]
1525
        sub     eax, sizeof.ohci_gtd
1532
        sub     eax, sizeof.ohci_gtd
1526
        call    get_phys_addr
1533
        call    get_phys_addr
1527
        or      eax, edx
1534
        or      eax, edx
1528
        mov     [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
1535
        mov     [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
1529
        push    ebx
1536
        push    ebx
1530
        mov     ebx, ecx
1537
        mov     ebx, ecx
1531
        call    ohci_notify_new_work
1538
        call    ohci_notify_new_work
1532
        pop     ebx
1539
        pop     ebx
1533
        pop     edx eax
1540
        pop     edx eax
1534
        jmp     .notify
1541
        jmp     .notify
1535
; 7d. Abort the entire transfer.
1542
; 7d. Abort the entire transfer.
1536
; There are two cases: either there is only one transfer stage
1543
; There are two cases: either there is only one transfer stage
1537
; (everything except control transfers), then ebx points to the last TD and
1544
; (everything except control transfers), then ebx points to the last TD and
1538
; all previous TD were unlinked and dismissed (if possible),
1545
; all previous TD were unlinked and dismissed (if possible),
1539
; or there are several stages (a control transfer) and ebx points to the last
1546
; or there are several stages (a control transfer) and ebx points to the last
1540
; TD of Data or Status stage (usb_is_final_packet does not stop in Setup stage,
1547
; TD of Data or Status stage (usb_is_final_packet does not stop in Setup stage,
1541
; because Setup stage can not produce short packets); for Data stage, we need
1548
; because Setup stage can not produce short packets); for Data stage, we need
1542
; to unlink and free (if possible) one more TD and advance ebx to the next one.
1549
; to unlink and free (if possible) one more TD and advance ebx to the next one.
1543
.no_underrun:
1550
.no_underrun:
1544
        cmp     [ebx+usb_gtd.Callback], 0
1551
        cmp     [ebx+usb_gtd.Callback], 0
1545
        jnz     .halted
1552
        jnz     .halted
1546
        cmp     ebx, [.current_item]
1553
        cmp     ebx, [.current_item]
1547
        push    [ebx+usb_gtd.NextVirt]
1554
        push    [ebx+usb_gtd.NextVirt]
1548
        jz      @f
1555
        jz      @f
1549
        stdcall usb1_free_general_td, ebx
1556
        stdcall usb1_free_general_td, ebx
1550
@@:
1557
@@:
1551
        pop     ebx
1558
        pop     ebx
1552
        call    usb_unlink_td
1559
        call    usb_unlink_td
1553
.halted:
1560
.halted:
1554
; 7e. For bulk/interrupt transfers we have no choice but halt the queue,
1561
; 7e. For bulk/interrupt transfers we have no choice but halt the queue,
1555
; the driver should intercede (through some API which is not written yet).
1562
; the driver should intercede (through some API which is not written yet).
1556
; Control pipes normally recover at the next SETUP transaction (first stage
1563
; Control pipes normally recover at the next SETUP transaction (first stage
1557
; of any control transfer), so we hope on the best and just advance the queue
1564
; of any control transfer), so we hope on the best and just advance the queue
1558
; to the next transfer. (According to the standard, "A control pipe may also
1565
; to the next transfer. (According to the standard, "A control pipe may also
1559
; support functional stall as well, but this is not recommended.").
1566
; support functional stall as well, but this is not recommended.").
1560
; Advance the transfer queue to the next descriptor.
1567
; Advance the transfer queue to the next descriptor.
1561
        mov     ecx, [ebx+usb_gtd.Pipe]
1568
        mov     ecx, [ebx+usb_gtd.Pipe]
1562
        mov     edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
1569
        mov     edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
1563
        and     edx, 2  ; keep toggleCarry bit
1570
        and     edx, 2  ; keep toggleCarry bit
1564
        cmp     [ecx+usb_pipe.Type], CONTROL_PIPE
1571
        cmp     [ecx+usb_pipe.Type], CONTROL_PIPE
1565
        jz      @f
1572
        jz      @f
1566
        inc     edx     ; set Halted bit
1573
        inc     edx     ; set Halted bit
1567
@@:
1574
@@:
1568
        jmp     .advance_queue
1575
        jmp     .advance_queue
1569
endp
1576
endp
1570
 
1577
 
1571
; This procedure is called when a pipe is closing (either due to API call
1578
; This procedure is called when a pipe is closing (either due to API call
1572
; or due to disconnect); it unlinks the pipe from the corresponding list.
1579
; or due to disconnect); it unlinks the pipe from the corresponding list.
1573
; esi -> usb_controller, ebx -> usb_pipe
1580
; esi -> usb_controller, ebx -> usb_pipe
1574
proc ohci_unlink_pipe
1581
proc ohci_unlink_pipe
1575
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1582
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1576
        jnz     @f
1583
        jnz     @f
1577
        mov     eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
1584
        mov     eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
1578
        bt      eax, 13
1585
        bt      eax, 13
1579
        setc    cl
1586
        setc    cl
1580
        bt      eax, 11
1587
        bt      eax, 11
1581
        setc    ch
1588
        setc    ch
1582
        shr     eax, 16
1589
        shr     eax, 16
1583
        stdcall usb1_interrupt_list_unlink, eax, ecx
1590
        stdcall usb1_interrupt_list_unlink, eax, ecx
1584
@@:
1591
@@:
1585
        mov     edx, [ebx+usb_pipe.NextVirt]
1592
        mov     edx, [ebx+usb_pipe.NextVirt]
1586
        mov     eax, [ebx+usb_pipe.PrevVirt]
1593
        mov     eax, [ebx+usb_pipe.PrevVirt]
1587
        mov     [edx+usb_pipe.PrevVirt], eax
1594
        mov     [edx+usb_pipe.PrevVirt], eax
1588
        mov     [eax+usb_pipe.NextVirt], edx
1595
        mov     [eax+usb_pipe.NextVirt], edx
1589
        mov     edx, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
1596
        mov     edx, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
1590
        mov     [eax+ohci_pipe.NextED-sizeof.ohci_pipe], edx
1597
        mov     [eax+ohci_pipe.NextED-sizeof.ohci_pipe], edx
1591
        ret
1598
        ret
1592
endp
1599
endp