[USBCCGP]
[reactos.git] / drivers / usb / usbccgp / fdo.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbccgp/fdo.c
5 * PURPOSE: USB device driver.
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
9 * Cameron Gutman
10 */
11
12 #include "usbccgp.h"
13
14 NTSTATUS
15 NTAPI
16 FDO_QueryCapabilitiesCompletionRoutine(
17 IN PDEVICE_OBJECT DeviceObject,
18 IN PIRP Irp,
19 IN PVOID Context)
20 {
21 //
22 // set event
23 //
24 KeSetEvent((PRKEVENT)Context, 0, FALSE);
25
26 //
27 // completion is done in the HidClassFDO_QueryCapabilities routine
28 //
29 return STATUS_MORE_PROCESSING_REQUIRED;
30 }
31
32 NTSTATUS
33 FDO_QueryCapabilities(
34 IN PDEVICE_OBJECT DeviceObject,
35 IN OUT PDEVICE_CAPABILITIES Capabilities)
36 {
37 PIRP Irp;
38 KEVENT Event;
39 NTSTATUS Status;
40 PIO_STACK_LOCATION IoStack;
41 PFDO_DEVICE_EXTENSION FDODeviceExtension;
42
43 //
44 // get device extension
45 //
46 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
47 ASSERT(FDODeviceExtension->Common.IsFDO);
48
49 //
50 // init event
51 //
52 KeInitializeEvent(&Event, NotificationEvent, FALSE);
53
54 //
55 // now allocte the irp
56 //
57 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
58 if (!Irp)
59 {
60 //
61 // no memory
62 //
63 return STATUS_INSUFFICIENT_RESOURCES;
64 }
65
66 //
67 // get next stack location
68 //
69 IoStack = IoGetNextIrpStackLocation(Irp);
70
71 //
72 // init stack location
73 //
74 IoStack->MajorFunction = IRP_MJ_PNP;
75 IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
76 IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities;
77
78 //
79 // set completion routine
80 //
81 IoSetCompletionRoutine(Irp, FDO_QueryCapabilitiesCompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE);
82
83 //
84 // init capabilities
85 //
86 RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
87 Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
88 Capabilities->Version = 1; // FIXME hardcoded constant
89 Capabilities->Address = MAXULONG;
90 Capabilities->UINumber = MAXULONG;
91
92 //
93 // pnp irps have default completion code
94 //
95 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
96
97 //
98 // call lower device
99 //
100 Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
101 if (Status == STATUS_PENDING)
102 {
103 //
104 // wait for completion
105 //
106 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
107 }
108
109 //
110 // get status
111 //
112 Status = Irp->IoStatus.Status;
113
114 //
115 // complete request
116 //
117 IoFreeIrp(Irp);
118
119 //
120 // done
121 //
122 return Status;
123 }
124
125 NTSTATUS
126 FDO_DeviceRelations(
127 PDEVICE_OBJECT DeviceObject,
128 PIRP Irp)
129 {
130 UNIMPLEMENTED
131 ASSERT(FALSE);
132 return STATUS_NOT_IMPLEMENTED;
133 }
134
135 NTSTATUS
136 FDO_StartDevice(
137 PDEVICE_OBJECT DeviceObject,
138 PIRP Irp)
139 {
140 NTSTATUS Status;
141 PFDO_DEVICE_EXTENSION FDODeviceExtension;
142
143 //
144 // get device extension
145 //
146 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
147 ASSERT(FDODeviceExtension->Common.IsFDO);
148
149 //
150 // first start lower device
151 //
152 Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp);
153
154 if (!NT_SUCCESS(Status))
155 {
156 //
157 // failed to start lower device
158 //
159 DPRINT1("FDO_StartDevice lower device failed to start with %x\n", Status);
160 return Status;
161 }
162
163 // get descriptors
164 Status = USBCCGP_GetDescriptors(DeviceObject);
165 if (!NT_SUCCESS(Status))
166 {
167 // failed to start lower device
168 DPRINT1("FDO_StartDevice failed to get descriptors with %x\n", Status);
169 return Status;
170 }
171
172 // get capabilities
173 Status = FDO_QueryCapabilities(DeviceObject, &FDODeviceExtension->Capabilities);
174 if (!NT_SUCCESS(Status))
175 {
176 // failed to start lower device
177 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
178 return Status;
179 }
180
181 // now select the configuration
182 Status = USBCCGP_SelectConfiguration(DeviceObject, FDODeviceExtension);
183 if (!NT_SUCCESS(Status))
184 {
185 // failed to select interface
186 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
187 return Status;
188 }
189
190 // query bus interface
191 USBCCGP_QueryInterface(FDODeviceExtension->NextDeviceObject, &FDODeviceExtension->BusInterface);
192
193 // now enumerate the functions
194 Status = USBCCGP_EnumerateFunctions(DeviceObject);
195 if (!NT_SUCCESS(Status))
196 {
197 // failed to enumerate functions
198 DPRINT1("Failed to enumerate functions with %x\n", Status);
199 return Status;
200 }
201
202 //
203 // sanity checks
204 //
205 ASSERT(FDODeviceExtension->FunctionDescriptorCount);
206 ASSERT(FDODeviceExtension->FunctionDescriptor);
207
208 //
209 // FIXME:create PDO for each function
210 //
211 ASSERT(FALSE);
212 return Status;
213 }
214
215
216 NTSTATUS
217 FDO_HandlePnp(
218 PDEVICE_OBJECT DeviceObject,
219 PIRP Irp)
220 {
221 PIO_STACK_LOCATION IoStack;
222 NTSTATUS Status;
223 PFDO_DEVICE_EXTENSION FDODeviceExtension;
224
225 // get device extension
226 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
227 ASSERT(FDODeviceExtension->Common.IsFDO);
228
229
230 // get stack location
231 IoStack = IoGetCurrentIrpStackLocation(Irp);
232
233 switch(IoStack->MinorFunction)
234 {
235 case IRP_MN_START_DEVICE:
236 {
237 Status = FDO_StartDevice(DeviceObject, Irp);
238 break;
239 }
240 case IRP_MN_QUERY_DEVICE_RELATIONS:
241 {
242 Status = FDO_DeviceRelations(DeviceObject, Irp);
243 break;
244 }
245 case IRP_MN_QUERY_CAPABILITIES:
246 {
247 //
248 // copy capabilities
249 //
250 RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
251 Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp);
252 if (NT_SUCCESS(Status))
253 {
254 //
255 // surprise removal ok
256 //
257 IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE;
258 }
259 break;
260 }
261 default:
262 {
263 //
264 // forward irp to next device object
265 //
266 IoSkipCurrentIrpStackLocation(Irp);
267 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
268 }
269
270 }
271
272 //
273 // complete request
274 //
275 Irp->IoStatus.Status = Status;
276 IoCompleteRequest(Irp, IO_NO_INCREMENT);
277 return Status;
278
279
280 }
281
282 NTSTATUS
283 FDO_Dispatch(
284 PDEVICE_OBJECT DeviceObject,
285 PIRP Irp)
286 {
287 PIO_STACK_LOCATION IoStack;
288 NTSTATUS Status;
289
290 /* get stack location */
291 IoStack = IoGetCurrentIrpStackLocation(Irp);
292
293 switch(IoStack->MajorFunction)
294 {
295 case IRP_MJ_PNP:
296 return FDO_HandlePnp(DeviceObject, Irp);
297 default:
298 DPRINT1("FDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
299 ASSERT(FALSE);
300 Status = Irp->IoStatus.Status;
301 IoCompleteRequest(Irp, IO_NO_INCREMENT);
302 return Status;
303 }
304 }
305
306