9ec3612a0d0ae3a399dae6589aab3b175223c15b
[reactos.git] / drivers / usb / usbuhci_new / roothub.c
1 #include "usbuhci.h"
2
3 #define NDEBUG
4 #include <debug.h>
5
6 VOID
7 NTAPI
8 UhciRHGetRootHubData(IN PVOID uhciExtension,
9 IN PVOID rootHubData)
10 {
11 PUHCI_EXTENSION UhciExtension = uhciExtension;
12 PUSBPORT_ROOT_HUB_DATA RootHubData = rootHubData;
13 USBPORT_HUB_11_CHARACTERISTICS HubCharacteristics;
14
15 DPRINT("UhciRHGetRootHubData: ...\n");
16
17 HubCharacteristics.AsUSHORT = 0;
18 HubCharacteristics.PowerControlMode = 1;
19 HubCharacteristics.NoPowerSwitching = 1;
20 HubCharacteristics.OverCurrentProtectionMode = 1;
21
22 if (UhciExtension->HcFlavor != UHCI_Piix4)
23 HubCharacteristics.NoOverCurrentProtection = 1;
24
25 RootHubData->NumberOfPorts = UHCI_NUM_ROOT_HUB_PORTS;
26 RootHubData->HubCharacteristics.Usb11HubCharacteristics = HubCharacteristics;
27 RootHubData->PowerOnToPowerGood = 1;
28 RootHubData->HubControlCurrent = 0;
29 }
30
31 MPSTATUS
32 NTAPI
33 UhciRHGetStatus(IN PVOID uhciExtension,
34 IN PUSHORT Status)
35 {
36 DPRINT("UhciRHGetStatus: ...\n");
37 *Status = UHCI_RH_STATUS_SUCCESS;
38 return MP_STATUS_SUCCESS;
39 }
40
41 MPSTATUS
42 NTAPI
43 UhciRHGetPortStatus(IN PVOID uhciExtension,
44 IN USHORT Port,
45 IN PUSB_PORT_STATUS_AND_CHANGE PortStatus)
46 {
47 PUHCI_EXTENSION UhciExtension = uhciExtension;
48 PUHCI_HW_REGISTERS BaseRegister;
49 PUSHORT PortControlRegister;
50 UHCI_PORT_STATUS_CONTROL PortControl;
51 ULONG PortBit;
52 USB_20_PORT_STATUS portStatus;
53 USB_20_PORT_CHANGE portChange;
54
55 //DPRINT("UhciRHGetPortStatus: ...\n");
56
57 ASSERT(Port);
58
59 BaseRegister = UhciExtension->BaseRegister;
60 PortControlRegister = &BaseRegister->PortControl[Port-1].AsUSHORT;
61 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
62
63 portStatus.AsUshort16 = 0;
64 portChange.AsUshort16 = 0;
65
66 portStatus.CurrentConnectStatus = PortControl.CurrentConnectStatus;
67 portStatus.PortEnabledDisabled = PortControl.PortEnabledDisabled;
68
69 if (PortControl.Suspend == 1 &&
70 PortControl.PortEnabledDisabled == 1)
71 {
72 portStatus.Suspend = 1;
73 }
74 else
75 {
76 portStatus.Suspend = 0;
77 }
78
79 //if (UhciExtension->HcFlavor == UHCI_Piix4) // check will work after supporting HcFlavor in usbport.
80 if (TRUE)
81 {
82 portStatus.OverCurrent = PortControl.Reserved2 & 1;
83 portStatus.PortPower = (~PortControl.Reserved2 & 1);
84 portChange.OverCurrentIndicatorChange = (PortControl.Reserved2 & 2) != 0;
85 }
86 else
87 {
88 portStatus.OverCurrent = 0;
89 portStatus.PortPower = 1;
90 portChange.OverCurrentIndicatorChange = 0;
91 }
92
93 portStatus.HighSpeedDeviceAttached = 0;
94
95 portStatus.Reset = PortControl.PortReset;
96 portStatus.LowSpeedDeviceAttached = PortControl.LowSpeedDevice;
97 portChange.ConnectStatusChange = PortControl.ConnectStatusChange;
98
99 PortBit = 1 << (Port - 1);
100
101 if (UhciExtension->ResetPortMask & PortBit)
102 {
103 portChange.ConnectStatusChange = 0;
104 portChange.PortEnableDisableChange = 0;
105 }
106 else
107 {
108 portChange.PortEnableDisableChange = PortControl.PortEnableDisableChange;
109 }
110
111 if (UhciExtension->SuspendChangePortMask & PortBit)
112 portChange.SuspendChange = 1;
113
114 if (UhciExtension->ResetChangePortMask & PortBit)
115 portChange.ResetChange = 1;
116
117 PortStatus->PortStatus.Usb20PortStatus = portStatus;
118 PortStatus->PortChange.Usb20PortChange = portChange;
119
120 //DPRINT("UhciRHGetPortStatus: PortControl.AsUSHORT[%x] - %X, PortStatus - %X\n",
121 // Port,
122 // PortControl.AsUSHORT,
123 // PortStatus->AsUlong32);
124
125 return MP_STATUS_SUCCESS;
126 }
127
128 MPSTATUS
129 NTAPI
130 UhciRHGetHubStatus(IN PVOID uhciExtension,
131 IN PUSB_HUB_STATUS_AND_CHANGE HubStatus)
132 {
133 //DPRINT("UhciRHGetHubStatus: ...\n");
134 HubStatus->AsUlong32 = 0;
135 return MP_STATUS_SUCCESS;
136 }
137
138 VOID
139 NTAPI
140 UhciRHPortResetComplete(IN PVOID uhciExtension,
141 IN PVOID pPort)
142 {
143 PUHCI_EXTENSION UhciExtension = uhciExtension;
144 ULONG ix;
145 PUHCI_HW_REGISTERS BaseRegister;
146 PUSHORT PortControlRegister;
147 UHCI_PORT_STATUS_CONTROL PortControl;
148 USHORT Port;
149
150 DPRINT("UhciRHPortResetComplete: ...\n");
151
152 BaseRegister = UhciExtension->BaseRegister;
153
154 Port = *(PUSHORT)pPort;
155 ASSERT(Port);
156
157 PortControlRegister = &BaseRegister->PortControl[Port - 1].AsUSHORT;
158 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
159
160 PortControl.ConnectStatusChange = 0;
161 PortControl.PortEnableDisableChange = 0;
162 PortControl.PortReset = 0;
163
164 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
165
166 while (UhciHardwarePresent(UhciExtension))
167 {
168 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
169
170 if (PortControl.PortReset == 0)
171 break;
172 }
173
174 for (ix = 0; ix < 10; ++ix)
175 {
176 KeStallExecutionProcessor(50);
177
178 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
179
180 if (PortControl.PortEnabledDisabled == 1)
181 break;
182
183 PortControl.PortEnabledDisabled = 1;
184 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
185 }
186
187 PortControl.ConnectStatusChange = 1;
188 PortControl.PortEnableDisableChange = 1;
189 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
190
191 if (UhciExtension->HcFlavor == UHCI_VIA &&
192 UhciExtension->HcFlavor == UHCI_VIA_x01 &&
193 UhciExtension->HcFlavor == UHCI_VIA_x02 &&
194 UhciExtension->HcFlavor == UHCI_VIA_x03 &&
195 UhciExtension->HcFlavor == UHCI_VIA_x04)
196 {
197 DPRINT("UhciRHPortResetComplete: Via chip. FIXME\n");
198 DbgBreakPoint();
199 return;
200 }
201
202 UhciExtension->ResetChangePortMask |= (1 << (Port - 1));
203 UhciExtension->ResetPortMask &= ~(1 << (Port - 1));
204
205 RegPacket.UsbPortInvalidateRootHub(UhciExtension);
206 }
207
208 VOID
209 NTAPI
210 UhciRHSetFeaturePortResetWorker(IN PUHCI_EXTENSION UhciExtension,
211 IN PUSHORT pPort)
212 {
213 PUHCI_HW_REGISTERS BaseRegister;
214 PUSHORT PortControlRegister;
215 UHCI_PORT_STATUS_CONTROL PortControl;
216 USHORT Port;
217
218 DPRINT("UhciRHSetFeaturePortResetWorker: ...\n");
219
220 BaseRegister = UhciExtension->BaseRegister;
221
222 Port = *(PUSHORT)pPort;
223 ASSERT(Port);
224
225 PortControlRegister = &BaseRegister->PortControl[Port - 1].AsUSHORT;
226 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
227
228 PortControl.ConnectStatusChange = 0;
229 PortControl.PortEnableDisableChange = 0;
230 PortControl.PortReset = 1;
231
232 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
233
234 RegPacket.UsbPortRequestAsyncCallback(UhciExtension,
235 10, // TimerValue
236 pPort,
237 sizeof(pPort),
238 UhciRHPortResetComplete);
239 }
240
241 MPSTATUS
242 NTAPI
243 UhciRHSetFeaturePortReset(IN PVOID uhciExtension,
244 IN USHORT Port)
245 {
246 PUHCI_EXTENSION UhciExtension = uhciExtension;
247 ULONG ResetPortMask;
248 ULONG PortBit;
249
250 DPRINT("UhciRHSetFeaturePortReset: ...\n");
251
252 ASSERT(Port);
253
254 ResetPortMask = UhciExtension->ResetPortMask;
255 PortBit = 1 << (Port - 1);
256
257 if (ResetPortMask & PortBit)
258 return MP_STATUS_FAILURE;
259
260 UhciExtension->ResetPortMask = ResetPortMask | PortBit;
261
262 if (UhciExtension->HcFlavor == UHCI_VIA &&
263 UhciExtension->HcFlavor == UHCI_VIA_x01 &&
264 UhciExtension->HcFlavor == UHCI_VIA_x02 &&
265 UhciExtension->HcFlavor == UHCI_VIA_x03 &&
266 UhciExtension->HcFlavor == UHCI_VIA_x04)
267 {
268 DPRINT1("UhciRHSetFeaturePortReset: Via chip. FIXME\n");
269 return MP_STATUS_SUCCESS;
270 }
271
272 UhciRHSetFeaturePortResetWorker(UhciExtension, &Port);
273
274 return MP_STATUS_SUCCESS;
275 }
276
277 MPSTATUS
278 NTAPI
279 UhciRHSetFeaturePortPower(IN PVOID uhciExtension,
280 IN USHORT Port)
281 {
282 DPRINT("UhciRHSetFeaturePortPower: ...\n");
283 ASSERT(Port);
284 return MP_STATUS_SUCCESS;
285 }
286
287 MPSTATUS
288 NTAPI
289 UhciRHPortEnable(IN PVOID uhciExtension,
290 IN USHORT Port,
291 IN BOOLEAN IsSet)
292 {
293 PUHCI_EXTENSION UhciExtension = uhciExtension;
294 PUHCI_HW_REGISTERS BaseRegister;
295 PUSHORT PortControlRegister;
296 UHCI_PORT_STATUS_CONTROL PortControl;
297
298 DPRINT("UhciRHPortEnable: ...\n");
299
300 ASSERT(Port);
301
302 BaseRegister = UhciExtension->BaseRegister;
303 PortControlRegister = &BaseRegister->PortControl[Port-1].AsUSHORT;
304
305 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
306
307 PortControl.ConnectStatusChange = 0;
308 PortControl.PortEnableDisableChange = 0;
309
310 if (IsSet)
311 PortControl.PortEnabledDisabled = 1;
312 else
313 PortControl.PortEnabledDisabled = 0;
314
315 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
316
317 return MP_STATUS_SUCCESS;
318 }
319
320 MPSTATUS
321 NTAPI
322 UhciRHSetFeaturePortEnable(IN PVOID uhciExtension,
323 IN USHORT Port)
324 {
325 PUHCI_EXTENSION UhciExtension = uhciExtension;
326 DPRINT("UhciRHSetFeaturePortEnable: ...\n");
327 ASSERT(Port);
328 return UhciRHPortEnable(UhciExtension, Port, TRUE);
329 }
330
331 MPSTATUS
332 NTAPI
333 UhciRHSetFeaturePortSuspend(IN PVOID uhciExtension,
334 IN USHORT Port)
335 {
336 DPRINT("UhciRHSetFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
337 ASSERT(Port);
338 return MP_STATUS_SUCCESS;
339 }
340
341 MPSTATUS
342 NTAPI
343 UhciRHClearFeaturePortEnable(IN PVOID uhciExtension,
344 IN USHORT Port)
345 {
346 PUHCI_EXTENSION UhciExtension = uhciExtension;
347 DPRINT("UhciRHClearFeaturePortEnable: ...\n");
348 ASSERT(Port);
349 return UhciRHPortEnable(UhciExtension, Port, FALSE);
350 }
351
352 MPSTATUS
353 NTAPI
354 UhciRHClearFeaturePortPower(IN PVOID uhciExtension,
355 IN USHORT Port)
356 {
357 DPRINT("UhciRHClearFeaturePortPower: UNIMPLEMENTED. FIXME\n");
358 ASSERT(Port);
359 return MP_STATUS_SUCCESS;
360 }
361
362 MPSTATUS
363 NTAPI
364 UhciRHClearFeaturePortSuspend(IN PVOID uhciExtension,
365 IN USHORT Port)
366 {
367 DPRINT("UhciRHClearFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
368 ASSERT(Port);
369 return MP_STATUS_SUCCESS;
370 }
371
372 MPSTATUS
373 NTAPI
374 UhciRHClearFeaturePortEnableChange(IN PVOID uhciExtension,
375 IN USHORT Port)
376 {
377 PUHCI_EXTENSION UhciExtension = uhciExtension;
378 PUHCI_HW_REGISTERS BaseRegister;
379 PUSHORT PortControlRegister;
380 UHCI_PORT_STATUS_CONTROL PortControl;
381
382 DPRINT("UhciRHClearFeaturePortEnableChange: ...\n");
383
384 ASSERT(Port);
385
386 BaseRegister = UhciExtension->BaseRegister;
387 PortControlRegister = (PUSHORT)&BaseRegister->PortControl[Port - 1];
388 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
389
390 PortControl.ConnectStatusChange = 0;
391 PortControl.PortEnableDisableChange = 1;
392 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
393
394 return MP_STATUS_SUCCESS;
395 }
396
397 MPSTATUS
398 NTAPI
399 UhciRHClearFeaturePortConnectChange(IN PVOID uhciExtension,
400 IN USHORT Port)
401 {
402 PUHCI_EXTENSION UhciExtension = uhciExtension;
403 PUHCI_HW_REGISTERS BaseRegister;
404 PUSHORT PortControlRegister;
405 UHCI_PORT_STATUS_CONTROL PortControl;
406
407 DPRINT("UhciRHClearFeaturePortConnectChange: Port - %04X\n", Port);
408
409 ASSERT(Port);
410
411 BaseRegister = UhciExtension->BaseRegister;
412 PortControlRegister = (PUSHORT)&BaseRegister->PortControl[Port - 1];
413 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
414
415 if (PortControl.ConnectStatusChange == 1)
416 {
417 /* WC (Write Clear) bits */
418 PortControl.PortEnableDisableChange = 0;
419 PortControl.ConnectStatusChange = 1;
420 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
421 }
422
423 return MP_STATUS_SUCCESS;
424 }
425
426 MPSTATUS
427 NTAPI
428 UhciRHClearFeaturePortResetChange(IN PVOID uhciExtension,
429 IN USHORT Port)
430 {
431 PUHCI_EXTENSION UhciExtension = uhciExtension;
432 DPRINT("UhciRHClearFeaturePortResetChange: ...\n");
433 ASSERT(Port);
434 UhciExtension->ResetChangePortMask &= ~(1 << (Port - 1));
435 return MP_STATUS_SUCCESS;
436 }
437
438 MPSTATUS
439 NTAPI
440 UhciRHClearFeaturePortSuspendChange(IN PVOID uhciExtension,
441 IN USHORT Port)
442 {
443 DPRINT("UhciRHClearFeaturePortSuspendChange: UNIMPLEMENTED. FIXME\n");
444 ASSERT(Port);
445 return MP_STATUS_SUCCESS;
446 }
447
448 MPSTATUS
449 NTAPI
450 UhciRHClearFeaturePortOvercurrentChange(IN PVOID uhciExtension,
451 IN USHORT Port)
452 {
453 DPRINT("UhciRHClearFeaturePortOvercurrentChange: UNIMPLEMENTED. FIXME\n");
454 ASSERT(Port);
455 return MP_STATUS_SUCCESS;
456 }
457
458 VOID
459 NTAPI
460 UhciRHDisableIrq(IN PVOID uhciExtension)
461 {
462 /* Do nothing */
463 return;
464 }
465
466 VOID
467 NTAPI
468 UhciRHEnableIrq(IN PVOID uhciExtension)
469 {
470 /* Do nothing */
471 return;
472 }
473