2 #include <initguid.h>
\r
5 #if defined (EVENT_TRACING)
\r
12 #define MAX_ID_LEN 80
\r
15 EvtDeviceProcessQueryInterfaceRequest(
\r
16 IN WDFDEVICE Device,
\r
17 IN LPGUID InterfaceType,
\r
18 IN OUT PINTERFACE ExposedInterface,
\r
19 IN OUT PVOID ExposedInterfaceSpecificData
\r
22 PPDO_DEVICE_DATA p_pdo = PdoGetData(Device);
\r
23 PFDO_DEVICE_DATA p_fdo = p_pdo->p_fdo;
\r
24 PMLX4_BUS_IB_INTERFACE p_ib_ifc = (PMLX4_BUS_IB_INTERFACE)ExposedInterface;
\r
26 UNUSED_PARAM(InterfaceType);
\r
27 UNUSED_PARAM(ExposedInterfaceSpecificData);
\r
29 if (p_fdo->pci_dev.dev) {
\r
30 p_ib_ifc->p_ibdev = p_fdo->bus_ib_ifc.p_ibdev;
\r
31 p_ib_ifc->pmlx4_dev = p_fdo->bus_ib_ifc.pmlx4_dev;
\r
32 p_ib_ifc->is_livefish = p_fdo->bus_ib_ifc.is_livefish;
\r
33 return STATUS_SUCCESS;
\r
36 p_ib_ifc->p_ibdev = NULL;
\r
37 p_ib_ifc->pmlx4_dev = NULL;
\r
38 p_ib_ifc->is_livefish = FALSE;
\r
39 return STATUS_UNSUCCESSFUL;
\r
46 __in WDFDEVICE Device,
\r
47 __in PWCHAR HardwareIds,
\r
48 __in PWCHAR DeviceDescription,
\r
53 Routine Description:
\r
55 This routine creates and initialize a PDO.
\r
66 PWDFDEVICE_INIT pDeviceInit = NULL;
\r
67 PPDO_DEVICE_DATA p_pdo = NULL;
\r
68 PFDO_DEVICE_DATA p_fdo;
\r
69 WDFDEVICE hChild = NULL;
\r
70 WDF_OBJECT_ATTRIBUTES pdoAttributes;
\r
71 WDF_DEVICE_PNP_CAPABILITIES pnpCaps;
\r
72 WDF_DEVICE_POWER_CAPABILITIES powerCaps;
\r
73 UNICODE_STRING compatId;
\r
74 DECLARE_CONST_UNICODE_STRING(deviceLocation, L"MLX4 Bus 0");
\r
75 UNICODE_STRING deviceId;
\r
76 DECLARE_UNICODE_STRING_SIZE(buffer, MAX_ID_LEN);
\r
78 MLX4_PRINT(TRACE_LEVEL_INFORMATION, MLX4_DBG_DRV, ("Entered CreatePdo\n"));
\r
80 RtlInitUnicodeString(&compatId, HardwareIds);
\r
84 // Allocate a WDFDEVICE_INIT structure and set the properties
\r
85 // so that we can create a device object for the child.
\r
87 pDeviceInit = WdfPdoInitAllocate(Device);
\r
89 if (pDeviceInit == NULL) {
\r
90 status = STATUS_INSUFFICIENT_RESOURCES;
\r
97 WdfDeviceInitSetDeviceType(pDeviceInit, FILE_DEVICE_BUS_EXTENDER);
\r
100 // Provide DeviceID, HardwareIDs, CompatibleIDs and InstanceId
\r
102 RtlInitUnicodeString(&deviceId,HardwareIds);
\r
104 status = WdfPdoInitAssignDeviceID(pDeviceInit, &deviceId);
\r
105 if (!NT_SUCCESS(status)) {
\r
110 // Note same string is used to initialize hardware id too
\r
112 status = WdfPdoInitAddHardwareID(pDeviceInit, &deviceId);
\r
113 if (!NT_SUCCESS(status)) {
\r
117 status = WdfPdoInitAddCompatibleID(pDeviceInit, &compatId);
\r
118 if (!NT_SUCCESS(status)) {
\r
122 status = RtlUnicodeStringPrintf(&buffer, L"%02d", SerialNo);
\r
123 if (!NT_SUCCESS(status)) {
\r
127 status = WdfPdoInitAssignInstanceID(pDeviceInit, &buffer);
\r
128 if (!NT_SUCCESS(status)) {
\r
133 // Provide a description about the device. This text is usually read from
\r
134 // the device. In the case of USB device, this text comes from the string
\r
135 // descriptor. This text is displayed momentarily by the PnP manager while
\r
136 // it's looking for a matching INF. If it finds one, it uses the Device
\r
137 // Description from the INF file or the friendly name created by
\r
138 // coinstallers to display in the device manager. FriendlyName takes
\r
139 // precedence over the DeviceDesc from the INF file.
\r
141 status = RtlUnicodeStringPrintf(&buffer,DeviceDescription , SerialNo );
\r
143 if (!NT_SUCCESS(status)) {
\r
148 // You can call WdfPdoInitAddDeviceText multiple times, adding device
\r
149 // text for multiple locales. When the system displays the text, it
\r
150 // chooses the text that matches the current locale, if available.
\r
151 // Otherwise it will use the string for the default locale.
\r
152 // The driver can specify the driver's default locale by calling
\r
153 // WdfPdoInitSetDefaultLocale.
\r
155 status = WdfPdoInitAddDeviceText(pDeviceInit,
\r
156 &buffer, &deviceLocation, 0x409);
\r
157 if (!NT_SUCCESS(status)) {
\r
161 WdfPdoInitSetDefaultLocale(pDeviceInit, 0x409);
\r
164 // Initialize the attributes to specify the size of PDO device extension.
\r
165 // All the state information private to the PDO will be tracked here.
\r
167 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&pdoAttributes, PDO_DEVICE_DATA);
\r
169 status = WdfDeviceCreate(&pDeviceInit, &pdoAttributes, &hChild);
\r
170 if (!NT_SUCCESS(status)) {
\r
175 // Once the device is created successfully, framework frees the
\r
176 // DeviceInit memory and sets the pDeviceInit to NULL. So don't
\r
177 // call any WdfDeviceInit functions after that.
\r
179 // Get the device context.
\r
181 p_pdo = PdoGetData(hChild);
\r
182 p_fdo = FdoGetData(Device);
\r
184 p_pdo->p_fdo = p_fdo;
\r
185 p_pdo->SerialNo = SerialNo;
\r
186 p_pdo->PdoDevice = hChild;
\r
189 // Set PnP properties for the child device.
\r
191 WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
\r
192 pnpCaps.Removable = WdfTrue;
\r
193 pnpCaps.EjectSupported = WdfTrue;
\r
194 pnpCaps.SurpriseRemovalOK = WdfTrue;
\r
196 pnpCaps.Address = SerialNo;
\r
197 pnpCaps.UINumber = SerialNo;
\r
199 WdfDeviceSetPnpCapabilities(hChild, &pnpCaps);
\r
202 // Set Power properties for the child device
\r
204 WDF_DEVICE_POWER_CAPABILITIES_INIT(&powerCaps);
\r
206 powerCaps.DeviceD1 = WdfTrue;
\r
207 powerCaps.WakeFromD1 = WdfTrue;
\r
208 powerCaps.DeviceWake = PowerDeviceD1;
\r
210 powerCaps.DeviceState[PowerSystemWorking] = PowerDeviceD0;
\r
211 powerCaps.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
\r
212 powerCaps.DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
\r
213 powerCaps.DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
\r
214 powerCaps.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
\r
215 powerCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
\r
217 WdfDeviceSetPowerCapabilities(hChild, &powerCaps);
\r
220 // Set bus IB interface
\r
222 p_fdo->bus_ib_ifc.port_id = (u8) SerialNo;
\r
223 p_fdo->bus_ib_ifc.pVipBusIfc = &p_fdo->mtnic_Ifc;
\r
224 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_pd_alloc = mlx4_pd_alloc;
\r
225 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_pd_free = mlx4_pd_free;
\r
226 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_uar_alloc = mlx4_uar_alloc;
\r
227 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_uar_free = mlx4_uar_free;
\r
228 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_mr_alloc = mlx4_mr_alloc;
\r
229 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_mr_free = mlx4_mr_free;
\r
230 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_mr_enable = mlx4_mr_enable;
\r
231 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_qp_get_region = mlx4_qp_get_region;
\r
232 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_alloc_hwq_res = mlx4_alloc_hwq_res;
\r
233 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_free_hwq_res = mlx4_free_hwq_res;
\r
235 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_cq_alloc = mlx4_cq_alloc;
\r
236 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_cq_free = mlx4_cq_free;
\r
237 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_cq_modify = mlx4_cq_modify;
\r
239 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_register_mac = mlx4_register_mac;
\r
240 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_unregister_mac = mlx4_unregister_mac;
\r
242 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_srq_alloc = mlx4_srq_alloc;
\r
243 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_srq_free = mlx4_srq_free;
\r
244 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_srq_invalidate = mlx4_srq_invalidate;
\r
245 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_srq_remove = mlx4_srq_remove;
\r
247 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_qp_alloc = mlx4_qp_alloc;
\r
248 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_qp_free = mlx4_qp_free;
\r
249 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_qp_remove = mlx4_qp_remove;
\r
250 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_qp_modify = mlx4_qp_modify;
\r
251 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_qp_to_ready = mlx4_qp_to_ready;
\r
252 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_qp_reserve_range = mlx4_qp_reserve_range;
\r
253 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_qp_release_range = mlx4_qp_release_range;
\r
255 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_alloc_cmd_mailbox = mlx4_alloc_cmd_mailbox;
\r
256 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_free_cmd_mailbox = mlx4_free_cmd_mailbox;
\r
257 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_cmd = imlx4_cmd;
\r
259 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_INIT_PORT = mlx4_INIT_PORT;
\r
260 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_CLOSE_PORT = mlx4_CLOSE_PORT;
\r
261 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_add_eq = mlx4_add_eq;
\r
262 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_remove_eq = mlx4_remove_eq;
\r
263 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_register_ev_cb = mlx4_reset_cb_register;
\r
264 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_unregister_ev_cb = mlx4_reset_cb_unregister;
\r
265 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_reset_request = mlx4_reset_request;
\r
266 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_reset_execute = mlx4_reset_execute;
\r
267 p_fdo->bus_ib_ifc.mlx4_interface.mlx4_reset_ready = mlx4_reset_ready;
\r
270 // Create a custom interface so that other drivers can
\r
271 // query (IRP_MN_QUERY_INTERFACE) and use our callbacks directly.
\r
273 p_fdo->bus_ib_ifc.i.Context = p_pdo;
\r
275 WDF_QUERY_INTERFACE_CONFIG_INIT( &p_pdo->qiMlx4Bus,
\r
276 (PINTERFACE) &p_fdo->bus_ib_ifc,
\r
277 &MLX4_BUS_IB_INTERFACE_GUID, EvtDeviceProcessQueryInterfaceRequest);
\r
279 status = WdfDeviceAddQueryInterface( hChild, &p_pdo->qiMlx4Bus );
\r
280 if (!NT_SUCCESS(status))
\r
284 // Expose also PCI.SYS interface for MLX4_HCA
\r
286 WDF_QUERY_INTERFACE_CONFIG_INIT( &p_pdo->qiPciBus,
\r
287 (PINTERFACE) &p_fdo->pci_dev.bus_pci_ifc,
\r
288 &GUID_BUS_INTERFACE_STANDARD, NULL);
\r
290 // TODO: Soft Reset - how tobar getting interface during RESET_IN_PROGRESS
\r
291 // maybe - using EvtDeviceProcessQueryInterfaceRequest
\r
292 status = WdfDeviceAddQueryInterface( hChild, &p_pdo->qiPciBus );
\r
293 if (!NT_SUCCESS(status))
\r
297 // Add this device to the FDO's collection of children.
\r
298 // After the child device is added to the static collection successfully,
\r
299 // driver must call WdfPdoMarkMissing to get the device deleted. It
\r
300 // shouldn't delete the child device directly by calling WdfObjectDelete.
\r
302 status = WdfFdoAddStaticChild(Device, hChild);
\r
303 if (!NT_SUCCESS(status)) {
\r
310 KdPrint(("BusEnum: Bus_CreatePdo failed %x\n", status));
\r
313 // Call WdfDeviceInitFree if you encounter an error before the
\r
314 // device is created. Once the device is created, framework
\r
315 // NULLs the pDeviceInit value.
\r
317 if (pDeviceInit != NULL) {
\r
318 WdfDeviceInitFree(pDeviceInit);
\r
322 WdfObjectDelete(hChild);
\r