TianoCore EDK2 master
Loading...
Searching...
No Matches
UsbCdcNcm.c
Go to the documentation of this file.
1
9#include "UsbCdcNcm.h"
10
11EFI_DRIVER_BINDING_PROTOCOL gUsbNcmDriverBinding = {
15 USB_NCM_DRIVER_VERSION,
16 NULL,
17 NULL
18};
19
29BOOLEAN
32 )
33{
34 EFI_STATUS Status;
35 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
36
37 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &InterfaceDescriptor);
38 if (EFI_ERROR (Status)) {
39 return FALSE;
40 }
41
42 if ((InterfaceDescriptor.InterfaceClass == USB_CDC_CLASS) &&
43 (InterfaceDescriptor.InterfaceSubClass == USB_CDC_NCM_SUBCLASS) &&
44 (InterfaceDescriptor.InterfaceProtocol == USB_NO_CLASS_PROTOCOL))
45 {
46 return TRUE;
47 }
48
49 return FALSE;
50}
51
66EFIAPI
69 IN EFI_HANDLE ControllerHandle,
70 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
71 )
72{
73 EFI_STATUS Status;
75
76 Status = gBS->OpenProtocol (
77 ControllerHandle,
78 &gEfiUsbIoProtocolGuid,
79 (VOID **)&UsbIo,
80 This->DriverBindingHandle,
81 ControllerHandle,
82 EFI_OPEN_PROTOCOL_BY_DRIVER
83 );
84 if (EFI_ERROR (Status)) {
85 return Status;
86 }
87
88 Status = IsSupportedDevice (UsbIo) ? EFI_SUCCESS : EFI_UNSUPPORTED;
89
90 gBS->CloseProtocol (
91 ControllerHandle,
92 &gEfiUsbIoProtocolGuid,
93 This->DriverBindingHandle,
94 ControllerHandle
95 );
96 return Status;
97}
98
111 IN EFI_DEVICE_PATH_PROTOCOL *UsbEthPath,
112 IN EFI_DEVICE_PATH_PROTOCOL *UsbCdcDataPath
113 )
114{
115 while (1) {
116 if ((UsbEthPath->Type == ACPI_DEVICE_PATH) && (UsbEthPath->SubType == ACPI_DP)) {
117 if (CompareMem ((ACPI_HID_DEVICE_PATH *)UsbCdcDataPath, (ACPI_HID_DEVICE_PATH *)UsbEthPath, sizeof (ACPI_HID_DEVICE_PATH))) {
118 return EFI_NOT_FOUND;
119 }
120 }
121
122 if ((UsbEthPath->Type == HARDWARE_DEVICE_PATH) && (UsbEthPath->SubType == HW_PCI_DP)) {
123 if (CompareMem ((PCI_DEVICE_PATH *)UsbCdcDataPath, (PCI_DEVICE_PATH *)UsbEthPath, sizeof (PCI_DEVICE_PATH))) {
124 return EFI_NOT_FOUND;
125 }
126 }
127
128 if ((UsbEthPath->Type == MESSAGING_DEVICE_PATH) && (UsbEthPath->SubType == MSG_USB_DP)) {
129 if (IsDevicePathEnd (NextDevicePathNode (UsbEthPath))) {
130 if (((USB_DEVICE_PATH *)UsbEthPath)->ParentPortNumber ==
131 ((USB_DEVICE_PATH *)UsbCdcDataPath)->ParentPortNumber)
132 {
133 return EFI_SUCCESS;
134 } else {
135 return EFI_NOT_FOUND;
136 }
137 } else {
138 if (CompareMem ((USB_DEVICE_PATH *)UsbCdcDataPath, (USB_DEVICE_PATH *)UsbEthPath, sizeof (USB_DEVICE_PATH))) {
139 return EFI_NOT_FOUND;
140 }
141 }
142 }
143
144 UsbEthPath = NextDevicePathNode (UsbEthPath);
145 UsbCdcDataPath = NextDevicePathNode (UsbCdcDataPath);
146 }
147}
148
159BOOLEAN
161 IN EFI_DEVICE_PATH_PROTOCOL *UsbEthPath,
162 IN OUT EFI_HANDLE *UsbCdcDataHandle
163 )
164{
165 EFI_STATUS Status;
166 UINTN Index;
167 UINTN HandleCount;
168 EFI_HANDLE *HandleBuffer;
169 EFI_USB_IO_PROTOCOL *UsbIo;
171 EFI_DEVICE_PATH_PROTOCOL *UsbCdcDataPath;
172
173 Status = gBS->LocateHandleBuffer (
175 &gEfiUsbIoProtocolGuid,
176 NULL,
177 &HandleCount,
178 &HandleBuffer
179 );
180 if (EFI_ERROR (Status)) {
181 return FALSE;
182 }
183
184 for (Index = 0; Index < HandleCount; Index++) {
185 Status = gBS->HandleProtocol (
186 HandleBuffer[Index],
187 &gEfiUsbIoProtocolGuid,
188 (VOID **)&UsbIo
189 );
190 ASSERT_EFI_ERROR (Status);
191
192 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);
193 ASSERT_EFI_ERROR (Status);
194
195 if ((Interface.InterfaceClass == USB_CDC_DATA_CLASS) &&
196 (Interface.InterfaceSubClass == USB_CDC_DATA_SUBCLASS) &&
197 (Interface.InterfaceProtocol == USB_NCM_NTB_PROTOCOL))
198 {
199 Status = gBS->HandleProtocol (
200 HandleBuffer[Index],
201 &gEfiDevicePathProtocolGuid,
202 (VOID **)&UsbCdcDataPath
203 );
204 if (EFI_ERROR (Status)) {
205 continue;
206 }
207
208 Status = IsSameDevice (UsbEthPath, UsbCdcDataPath);
209 if (!EFI_ERROR (Status)) {
210 CopyMem (UsbCdcDataHandle, &HandleBuffer[Index], sizeof (EFI_HANDLE));
211 FreePool (HandleBuffer);
212 return TRUE;
213 }
214 }
215 }
216
217 FreePool (HandleBuffer);
218 return FALSE;
219}
220
229VOID
230EFIAPI
232 IN EFI_EVENT Event,
233 IN VOID *Context
234 )
235{
236 EFI_STATUS Status;
237 UINTN Index;
238 UINTN HandleCount;
239 EFI_HANDLE *HandleBuffer;
240 EFI_USB_IO_PROTOCOL *UsbIo;
242
243 Status = gBS->LocateHandleBuffer (
245 &gEfiUsbIoProtocolGuid,
246 NULL,
247 &HandleCount,
248 &HandleBuffer
249 );
250 if (EFI_ERROR (Status)) {
251 return;
252 }
253
254 for (Index = 0; Index < HandleCount; Index++) {
255 Status = gBS->HandleProtocol (
256 HandleBuffer[Index],
257 &gEfiUsbIoProtocolGuid,
258 (VOID **)&UsbIo
259 );
260 ASSERT_EFI_ERROR (Status);
261
262 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);
263 ASSERT_EFI_ERROR (Status);
264
265 if ((Interface.InterfaceClass == USB_CDC_CLASS) &&
266 (Interface.InterfaceSubClass == USB_CDC_NCM_SUBCLASS) &&
267 (Interface.InterfaceProtocol == USB_NO_CLASS_PROTOCOL))
268 {
269 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
270 }
271 }
272
273 FreePool (HandleBuffer);
274 gBS->CloseEvent (Event);
275}
276
292EFIAPI
295 IN EFI_HANDLE ControllerHandle,
296 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
297 )
298{
299 EFI_STATUS Status;
300 VOID *Reg;
301 EFI_EVENT Event;
302 USB_ETHERNET_DRIVER *UsbEthDriver;
303 EFI_DEVICE_PATH_PROTOCOL *UsbEthPath;
304 EFI_HANDLE UsbCdcDataHandle;
305 EFI_USB_IO_PROTOCOL *UsbIo;
307
308 Status = gBS->OpenProtocol (
309 ControllerHandle,
310 &gEfiUsbIoProtocolGuid,
311 (VOID **)&UsbIo,
312 This->DriverBindingHandle,
313 ControllerHandle,
314 EFI_OPEN_PROTOCOL_BY_DRIVER
315 );
316 if (EFI_ERROR (Status)) {
317 return Status;
318 }
319
320 Status = gBS->OpenProtocol (
321 ControllerHandle,
322 &gEfiDevicePathProtocolGuid,
323 (VOID **)&UsbEthPath,
324 This->DriverBindingHandle,
325 ControllerHandle,
326 EFI_OPEN_PROTOCOL_GET_PROTOCOL
327 );
328 if (EFI_ERROR (Status)) {
329 gBS->CloseProtocol (
330 ControllerHandle,
331 &gEfiUsbIoProtocolGuid,
332 This->DriverBindingHandle,
333 ControllerHandle
334 );
335 return Status;
336 }
337
338 Status = IsUsbCdcData (UsbEthPath, &UsbCdcDataHandle) ? EFI_SUCCESS : EFI_UNSUPPORTED;
339 if (EFI_ERROR (Status)) {
340 gBS->CloseProtocol (
341 ControllerHandle,
342 &gEfiUsbIoProtocolGuid,
343 This->DriverBindingHandle,
344 ControllerHandle
345 );
346
347 Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, CallbackFunction, NULL, &Event);
348 if (EFI_ERROR (Status)) {
349 return Status;
350 }
351
352 Status = gBS->RegisterProtocolNotify (&gEfiUsbIoProtocolGuid, Event, &Reg);
353 return Status;
354 }
355
356 UsbEthDriver = AllocateZeroPool (sizeof (USB_ETHERNET_DRIVER));
357 if (!UsbEthDriver) {
358 gBS->CloseProtocol (
359 ControllerHandle,
360 &gEfiUsbIoProtocolGuid,
361 This->DriverBindingHandle,
362 ControllerHandle
363 );
364 return EFI_OUT_OF_RESOURCES;
365 }
366
367 Status = LoadAllDescriptor (UsbIo, &UsbEthDriver->Config);
368 ASSERT_EFI_ERROR (Status);
369
370 GetEndpoint (UsbIo, UsbEthDriver);
371
372 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);
373 ASSERT_EFI_ERROR (Status);
374
375 UsbEthDriver->Signature = USB_ETHERNET_SIGNATURE;
376 UsbEthDriver->NumOfInterface = Interface.InterfaceNumber;
377 UsbEthDriver->UsbCdcDataHandle = UsbCdcDataHandle;
378 UsbEthDriver->UsbIo = UsbIo;
379 UsbEthDriver->UsbEth.UsbEthReceive = UsbEthNcmReceive;
380 UsbEthDriver->UsbEth.UsbEthTransmit = UsbEthNcmTransmit;
381 UsbEthDriver->UsbEth.UsbEthInterrupt = UsbEthNcmInterrupt;
382 UsbEthDriver->UsbEth.UsbEthMacAddress = GetUsbEthMacAddress;
383 UsbEthDriver->UsbEth.UsbEthMaxBulkSize = UsbEthNcmBulkSize;
384 UsbEthDriver->UsbEth.UsbHeaderFunDescriptor = GetUsbHeaderFunDescriptor;
385 UsbEthDriver->UsbEth.UsbUnionFunDescriptor = GetUsbUnionFunDescriptor;
386 UsbEthDriver->UsbEth.UsbEthFunDescriptor = GetUsbEthFunDescriptor;
387 UsbEthDriver->UsbEth.SetUsbEthMcastFilter = SetUsbEthMcastFilter;
388 UsbEthDriver->UsbEth.SetUsbEthPowerPatternFilter = SetUsbEthPowerFilter;
389 UsbEthDriver->UsbEth.GetUsbEthPowerPatternFilter = GetUsbEthPowerFilter;
390 UsbEthDriver->UsbEth.SetUsbEthPacketFilter = SetUsbEthPacketFilter;
391 UsbEthDriver->UsbEth.GetUsbEthStatistic = GetUsbEthStatistic;
392
393 UsbEthDriver->BulkBuffer = AllocateZeroPool (USB_NCM_MAX_NTB_SIZE);
394
395 Status = gBS->InstallProtocolInterface (
396 &ControllerHandle,
397 &gEdkIIUsbEthProtocolGuid,
399 &(UsbEthDriver->UsbEth)
400 );
401 if (EFI_ERROR (Status)) {
402 gBS->CloseProtocol (
403 ControllerHandle,
404 &gEfiUsbIoProtocolGuid,
405 This->DriverBindingHandle,
406 ControllerHandle
407 );
408 FreePool (UsbEthDriver);
409 return Status;
410 }
411
412 return Status;
413}
414
429EFIAPI
432 IN EFI_HANDLE ControllerHandle,
433 IN UINTN NumberOfChildren,
434 IN EFI_HANDLE *ChildHandleBuffer
435 )
436{
437 EFI_STATUS Status;
438 EDKII_USB_ETHERNET_PROTOCOL *UsbEthProtocol;
439 USB_ETHERNET_DRIVER *UsbEthDriver;
440
441 Status = gBS->OpenProtocol (
442 ControllerHandle,
443 &gEdkIIUsbEthProtocolGuid,
444 (VOID **)&UsbEthProtocol,
445 This->DriverBindingHandle,
446 ControllerHandle,
447 EFI_OPEN_PROTOCOL_GET_PROTOCOL
448 );
449 if (EFI_ERROR (Status)) {
450 return Status;
451 }
452
453 UsbEthDriver = USB_ETHERNET_DEV_FROM_THIS (UsbEthProtocol);
454
455 Status = gBS->UninstallProtocolInterface (
456 ControllerHandle,
457 &gEdkIIUsbEthProtocolGuid,
458 UsbEthProtocol
459 );
460 if (EFI_ERROR (Status)) {
461 return Status;
462 }
463
464 Status = gBS->CloseProtocol (
465 ControllerHandle,
466 &gEfiUsbIoProtocolGuid,
467 This->DriverBindingHandle,
468 ControllerHandle
469 );
470 FreePool (UsbEthDriver->Config);
471 FreePool (UsbEthDriver->BulkBuffer);
472 FreePool (UsbEthDriver);
473 return Status;
474}
475
489EFIAPI
491 IN EFI_HANDLE ImageHandle,
492 IN EFI_SYSTEM_TABLE *SystemTable
493 )
494{
495 gUsbNcmDriverBinding.DriverBindingHandle = ImageHandle;
496 gUsbNcmDriverBinding.ImageHandle = ImageHandle;
497
498 return gBS->InstallMultipleProtocolInterfaces (
499 &gUsbNcmDriverBinding.DriverBindingHandle,
500 &gEfiDriverBindingProtocolGuid,
501 &gUsbNcmDriverBinding,
502 &gEfiComponentName2ProtocolGuid,
503 &gUsbNcmComponentName2,
504 NULL
505 );
506}
UINT64 UINTN
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define ACPI_DEVICE_PATH
Definition: DevicePath.h:190
#define MSG_USB_DP
Definition: DevicePath.h:418
#define ACPI_DP
Definition: DevicePath.h:195
#define HW_PCI_DP
Definition: DevicePath.h:73
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_STATUS EFIAPI GetUsbEthMacAddress(IN EDKII_USB_ETHERNET_PROTOCOL *This, OUT EFI_MAC_ADDRESS *MacAddress)
EFI_STATUS EFIAPI SetUsbEthPowerFilter(IN EDKII_USB_ETHERNET_PROTOCOL *This, IN UINT16 Value, IN UINT16 Length, IN VOID *PatternFilter)
EFI_STATUS EFIAPI SetUsbEthPacketFilter(IN EDKII_USB_ETHERNET_PROTOCOL *This, IN UINT16 Value)
VOID GetEndpoint(IN EFI_USB_IO_PROTOCOL *UsbIo, IN OUT USB_ETHERNET_DRIVER *UsbEthDriver)
EFI_STATUS EFIAPI GetUsbEthFunDescriptor(IN EDKII_USB_ETHERNET_PROTOCOL *This, OUT USB_ETHERNET_FUN_DESCRIPTOR *UsbEthFunDescriptor)
EFI_STATUS EFIAPI GetUsbEthPowerFilter(IN EDKII_USB_ETHERNET_PROTOCOL *This, IN UINT16 Value, OUT BOOLEAN *PatternActive)
EFI_STATUS LoadAllDescriptor(IN EFI_USB_IO_PROTOCOL *UsbIo, OUT EFI_USB_CONFIG_DESCRIPTOR **ConfigDesc)
EFI_STATUS EFIAPI GetUsbEthStatistic(IN EDKII_USB_ETHERNET_PROTOCOL *This, IN UINT16 FeatureSelector, OUT VOID *Statistic)
EFI_STATUS EFIAPI SetUsbEthMcastFilter(IN EDKII_USB_ETHERNET_PROTOCOL *This, IN UINT16 Value, IN VOID *McastAddr)
EFI_STATUS EFIAPI GetUsbHeaderFunDescriptor(IN EDKII_USB_ETHERNET_PROTOCOL *This, OUT USB_HEADER_FUN_DESCRIPTOR *UsbHeaderFunDescriptor)
EFI_STATUS EFIAPI GetUsbUnionFunDescriptor(IN EDKII_USB_ETHERNET_PROTOCOL *This, OUT USB_UNION_FUN_DESCRIPTOR *UsbUnionFunDescriptor)
EFI_STATUS EFIAPI UsbNcmDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: UsbCdcNcm.c:293
EFI_STATUS EFIAPI UsbNcmEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: UsbCdcNcm.c:490
BOOLEAN IsSupportedDevice(IN EFI_USB_IO_PROTOCOL *UsbIo)
Definition: UsbCdcNcm.c:30
EFI_STATUS IsSameDevice(IN EFI_DEVICE_PATH_PROTOCOL *UsbEthPath, IN EFI_DEVICE_PATH_PROTOCOL *UsbCdcDataPath)
Definition: UsbCdcNcm.c:110
EFI_STATUS EFIAPI UsbNcmDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: UsbCdcNcm.c:430
VOID EFIAPI CallbackFunction(IN EFI_EVENT Event, IN VOID *Context)
Definition: UsbCdcNcm.c:231
BOOLEAN IsUsbCdcData(IN EFI_DEVICE_PATH_PROTOCOL *UsbEthPath, IN OUT EFI_HANDLE *UsbCdcDataHandle)
Definition: UsbCdcNcm.c:160
EFI_STATUS EFIAPI UsbNcmDriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: UsbCdcNcm.c:67
EFI_STATUS EFIAPI UsbEthNcmTransmit(IN PXE_CDB *Cdb, IN EDKII_USB_ETHERNET_PROTOCOL *This, IN VOID *Packet, IN OUT UINTN *PacketLength)
EFI_STATUS EFIAPI UsbEthNcmReceive(IN PXE_CDB *Cdb, IN EDKII_USB_ETHERNET_PROTOCOL *This, IN OUT VOID *Packet, IN OUT UINTN *PacketLength)
EFI_STATUS EFIAPI UsbEthNcmBulkSize(IN EDKII_USB_ETHERNET_PROTOCOL *This, OUT UINTN *BulkSize)
EFI_STATUS EFIAPI UsbEthNcmInterrupt(IN EDKII_USB_ETHERNET_PROTOCOL *This, IN BOOLEAN IsNewTransfer, IN UINTN PollingInterval, IN EFI_USB_DEVICE_REQUEST *Request)