\r
#endif\r
\r
+static \r
NTSTATUS\r
__create_child(\r
__in WDFDEVICE Device,\r
return status;\r
}\r
\r
+static \r
NTSTATUS\r
__do_static_enumeration(\r
IN WDFDEVICE Device\r
NTSTATUS status = STATUS_SUCCESS;\r
int i;\r
int number_of_ib_ports;\r
-\r
- // TODO:Need to add an event log in the case of errors\r
+ PFDO_DEVICE_DATA p_fdo = FdoGetData(Device);\r
+ struct mlx4_dev *mdev = p_fdo->pci_dev.dev;\r
\r
MLX4_ENTER(MLX4_DBG_DRV);\r
\r
+ if ( p_fdo->children_created )\r
+ goto end;\r
+ \r
// eventually we'll have all information about children in Registry\r
// DriverEntry will read it into a Global storage and\r
// this routine will create all the children on base on this info\r
if(number_of_ib_ports > 0) {\r
status = __create_child(Device, BUS_HARDWARE_IDS, BUS_HARDWARE_DESCRIPTION, 0 );\r
if (!NT_SUCCESS(status)) {\r
- MLX4_PRINT(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (ib)failed with 0x%x\n", status));\r
+ MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (ib)failed with 0x%x\n", status));\r
}\r
}\r
\r
if(mlx4_is_eth_port(i)) {\r
status = __create_child(Device, ETH_HARDWARE_IDS, ETH_HARDWARE_DESCRIPTION, i+1 );\r
if (!NT_SUCCESS(status)) {\r
- MLX4_PRINT(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (eth) failed with 0x%x\n", status));\r
+ MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (eth) failed with 0x%x\n", status));\r
}\r
}\r
}\r
\r
+ p_fdo->children_created = TRUE;\r
+ \r
+end:\r
MLX4_EXIT( MLX4_DBG_DRV );\r
return status;\r
}\r
\r
+static \r
+NTSTATUS\r
+__start_card( \r
+ IN PFDO_DEVICE_DATA p_fdo \r
+ )\r
+{\r
+#ifndef USE_WDM_INTERRUPTS\r
+ int i;\r
+#endif\r
+ int err;\r
+ NTSTATUS status = STATUS_SUCCESS;\r
+ struct pci_dev *pdev = &p_fdo->pci_dev;\r
+\r
+ MLX4_ENTER(MLX4_DBG_DRV);\r
+\r
+ if ( p_fdo->card_started )\r
+ goto err; \r
+ \r
+ // enable the card\r
+ status = pci_hca_enable( &pdev->bus_pci_ifc, &pdev->pci_cfg_space );\r
+ if( !NT_SUCCESS( status ) ) \r
+ goto err;\r
+\r
+ //\r
+ // init the card\r
+ //\r
+\r
+#ifndef USE_WDM_INTERRUPTS\r
+ // enable interrupts for start up\r
+ for ( i = 0; i < MLX4_MAX_INTERRUPTS; ++i ) \r
+ WdfInterruptEnable(p_fdo->interrupt[i].WdfInterrupt);\r
+#endif \r
+\r
+ // NET library\r
+ err = mlx4_init_one( &p_fdo->pci_dev );\r
+ if (err) {\r
+ status = errno_to_ntstatus(err);\r
+ goto err;\r
+ }\r
+\r
+#ifndef USE_WDM_INTERRUPTS\r
+ //\r
+ // complete filling interrupt context (for more efficiency)\r
+ //\r
+ for ( i = 0; i < MLX4_MAX_INTERRUPTS; ++i ) {\r
+ struct mlx4_priv *priv = mlx4_priv( p_fdo->pci_dev.dev );\r
+ PINTERRUPT_DATA p_isr_ctx = WdfObjectGetTypedContext( \r
+ p_fdo->interrupt[i].WdfInterrupt, INTERRUPT_DATA );\r
+\r
+ p_isr_ctx->eq = &priv->eq_table.eq[i];\r
+ }\r
+#endif\r
+\r
+ //\r
+ // prepare MLX4 IB interface\r
+ //\r
+\r
+ // fill the header\r
+ p_fdo->bus_ib_ifc.i.Size = sizeof(MLX4_BUS_IB_INTERFACE);\r
+ p_fdo->bus_ib_ifc.i.Version = MLX4_BUS_IB_INTERFACE_VERSION;\r
+ // Let the framework handle reference counting.\r
+ p_fdo->bus_ib_ifc.i.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;\r
+ p_fdo->bus_ib_ifc.i.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;\r
+\r
+ p_fdo->bus_ib_ifc.pdev = &p_fdo->pci_dev;\r
+ p_fdo->bus_ib_ifc.p_ibdev = p_fdo->pci_dev.ib_dev;\r
+ p_fdo->bus_ib_ifc.pmlx4_dev = to_mdev(p_fdo->pci_dev.ib_dev)->dev;\r
+ p_fdo->bus_ib_ifc.is_livefish = mlx4_is_livefish(p_fdo->pci_dev.dev);\r
+\r
+ p_fdo->card_started = TRUE;\r
+\r
+err:\r
+ MLX4_EXIT( MLX4_DBG_DRV );\r
+ return status;\r
+}\r
+\r
+static\r
+void\r
+__stop_card(\r
+ IN PFDO_DEVICE_DATA p_fdo\r
+ )\r
+{\r
+ if ( p_fdo->card_started ) {\r
+ p_fdo->card_started = FALSE;\r
+ mlx4_remove_one( &p_fdo->pci_dev );\r
+ }\r
+}\r
+\r
+\r
NTSTATUS\r
EvtDeviceD0Entry(\r
IN WDFDEVICE Device,\r
)\r
{\r
NTSTATUS status = STATUS_SUCCESS;\r
- \r
- UNUSED_PARAM(Device);\r
- UNUSED_PARAM(PreviousState);\r
+ PFDO_DEVICE_DATA p_fdo = FdoGetData(Device);\r
+ struct pci_dev *pdev = &p_fdo->pci_dev;\r
+ struct mlx4_dev *mdev;\r
\r
MLX4_ENTER(MLX4_DBG_DRV);\r
\r
MLX4_PRINT(TRACE_LEVEL_INFORMATION, MLX4_DBG_DRV, ("PreviousState 0x%x\n", PreviousState));\r
\r
+ // start card (needed after Hibernetion)\r
+ if (PreviousState > WdfPowerDeviceD0)\r
+ __start_card( p_fdo );\r
+ mdev = pdev->dev;\r
+\r
+ // create child device\r
status = __do_static_enumeration(Device);\r
- if (!NT_SUCCESS(status)) {\r
- MLX4_PRINT(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__do_static_enumeration failed with 0x%x\n", status));\r
- }\r
+ if (!NT_SUCCESS(status)) {\r
+ MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__do_static_enumeration failed with 0x%x\n", status));\r
+ goto err;\r
+ }\r
\r
- {\r
- PFDO_DEVICE_DATA p_fdo = FdoGetData(Device);\r
- struct pci_dev *pdev = &p_fdo->pci_dev;\r
- struct mlx4_dev *mdev = pdev->dev;\r
-\r
- MLX4_PRINT_EV(TRACE_LEVEL_INFORMATION ,MLX4_DBG_DRV ,\r
- ("Ven %x Dev %d Fw %d.%d.%d Drv %s (%s), BD %s\n", \r
- (unsigned)pdev->ven_id, (unsigned)pdev->dev_id,\r
- (int) (mdev->caps.fw_ver >> 32),\r
- (int) (mdev->caps.fw_ver >> 16) & 0xffff, \r
- (int) (mdev->caps.fw_ver & 0xffff),\r
- DRV_VERSION, DRV_RELDATE, \r
- mlx4_is_livefish(mdev) ? "Y" : "N"\r
- ));\r
- }\r
+ // Log Success Message\r
+ MLX4_PRINT_EV(TRACE_LEVEL_INFORMATION ,MLX4_DBG_DRV ,\r
+ ("Ven %x Dev %d Fw %d.%d.%d, IsBurnDevice %s\n", \r
+ (unsigned)pdev->ven_id, (unsigned)pdev->dev_id,\r
+ (int) (mdev->caps.fw_ver >> 32),\r
+ (int) (mdev->caps.fw_ver >> 16) & 0xffff, \r
+ (int) (mdev->caps.fw_ver & 0xffff),\r
+ mlx4_is_livefish(mdev) ? "Y" : "N"\r
+ ));\r
\r
+err:\r
MLX4_EXIT( MLX4_DBG_DRV );\r
- return STATUS_SUCCESS;\r
+ return status;\r
}\r
\r
NTSTATUS\r
IN WDF_POWER_DEVICE_STATE TargetState\r
)\r
{\r
- UNUSED_PARAM(Device);\r
- UNUSED_PARAM(TargetState);\r
+ PFDO_DEVICE_DATA p_fdo = FdoGetData(Device);\r
+ \r
MLX4_ENTER(MLX4_DBG_DRV);\r
MLX4_PRINT(TRACE_LEVEL_INFORMATION, MLX4_DBG_DRV, ("TargetState 0x%x\n", TargetState));\r
+\r
+ if (TargetState > WdfPowerDeviceD0)\r
+ __stop_card( p_fdo );\r
+\r
MLX4_EXIT( MLX4_DBG_DRV );\r
return STATUS_SUCCESS;\r
}\r
return status;\r
}\r
\r
-\r
NTSTATUS\r
EvtPrepareHardware(\r
IN WDFDEVICE Device,\r
IN WDFCMRESLIST ResourcesTranslated\r
)\r
{\r
-#ifndef USE_WDM_INTERRUPTS\r
- int i;\r
-#endif\r
- int err;\r
NTSTATUS status;\r
PFDO_DEVICE_DATA p_fdo = FdoGetData(Device);\r
- struct pci_dev *pdev = &p_fdo->pci_dev;\r
\r
MLX4_ENTER(MLX4_DBG_DRV);\r
\r
goto err;\r
}\r
\r
- // enable the card\r
- status = pci_hca_enable( &pdev->bus_pci_ifc, &pdev->pci_cfg_space );\r
- if( !NT_SUCCESS( status ) ) \r
- goto err;\r
-\r
- //\r
- // init the card\r
- //\r
-\r
-#ifndef USE_WDM_INTERRUPTS\r
- // enable interrupts for start up\r
- for ( i = 0; i < MLX4_MAX_INTERRUPTS; ++i ) \r
- WdfInterruptEnable(p_fdo->interrupt[i].WdfInterrupt);\r
-#endif \r
-\r
- // NET library\r
- err = mlx4_init_one( &p_fdo->pci_dev );\r
- if (err) {\r
- status = errno_to_ntstatus(err);\r
- goto err;\r
- }\r
-\r
-#ifndef USE_WDM_INTERRUPTS\r
- //\r
- // complete filling interrupt context (for more efficiency)\r
- //\r
- for ( i = 0; i < MLX4_MAX_INTERRUPTS; ++i ) {\r
- struct mlx4_priv *priv = mlx4_priv( p_fdo->pci_dev.dev );\r
- PINTERRUPT_DATA p_isr_ctx = WdfObjectGetTypedContext( \r
- p_fdo->interrupt[i].WdfInterrupt, INTERRUPT_DATA );\r
-\r
- p_isr_ctx->eq = &priv->eq_table.eq[i];\r
- }\r
-#endif\r
-\r
- //\r
- // prepare MLX4 IB interface\r
- //\r
-\r
- // fill the header\r
- p_fdo->bus_ib_ifc.i.Size = sizeof(MLX4_BUS_IB_INTERFACE);\r
- p_fdo->bus_ib_ifc.i.Version = MLX4_BUS_IB_INTERFACE_VERSION;\r
- // Let the framework handle reference counting.\r
- p_fdo->bus_ib_ifc.i.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;\r
- p_fdo->bus_ib_ifc.i.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;\r
-\r
- p_fdo->bus_ib_ifc.pdev = &p_fdo->pci_dev;\r
- p_fdo->bus_ib_ifc.p_ibdev = p_fdo->pci_dev.ib_dev;\r
- p_fdo->bus_ib_ifc.pmlx4_dev = to_mdev(p_fdo->pci_dev.ib_dev)->dev;\r
- p_fdo->bus_ib_ifc.is_livefish = mlx4_is_livefish(p_fdo->pci_dev.dev);\r
-\r
- status = STATUS_SUCCESS;\r
+ // start the card\r
+ status = __start_card( p_fdo );\r
\r
err:\r
MLX4_EXIT( MLX4_DBG_DRV );\r
\r
MLX4_ENTER(MLX4_DBG_DRV);\r
\r
- mlx4_remove_one( &p_fdo->pci_dev );\r
+ __stop_card( p_fdo );\r
__put_resources( p_fdo );\r
\r
MLX4_EXIT( MLX4_DBG_DRV );\r
\r
#ifndef USE_WDM_FRAMEWORK\r
\r
+//\r
+// TODO: add support for Hibernate/Standby as in WDM version below\r
+//\r
+\r
#ifdef ALLOC_PRAGMA\r
#pragma alloc_text (INIT, DriverEntry)\r
#pragma alloc_text (PAGE, EvtDeviceAdd)\r
\r
HCA_ENTER( HCA_DBG_PNP );\r
\r
- for( i = 0; i < HCA_BAR_TYPE_MAX; i++ ) {\r
- if (pdev->bar[i].virt) {\r
- MmUnmapIoSpace( pdev->bar[i].virt, pdev->bar[i].size );\r
- cl_memclr( &pdev->bar[i], sizeof(hca_bar_t) );\r
+ if ( pdev )\r
+ for( i = 0; i < HCA_BAR_TYPE_MAX; i++ ) {\r
+ if (pdev->bar[i].virt) {\r
+ MmUnmapIoSpace( pdev->bar[i].virt, pdev->bar[i].size );\r
+ cl_memclr( &pdev->bar[i], sizeof(hca_bar_t) );\r
+ }\r
}\r
- }\r
\r
HCA_EXIT( HCA_DBG_PNP );\r
}\r
IN DEVICE_OBJECT* p_dev_obj,\r
IN void* context )\r
{\r
+ int err;\r
NTSTATUS status;\r
IO_STACK_LOCATION *pIoStack;\r
PFDO_DEVICE_DATA p_fdo;\r
HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_PO, \r
("***** Restart the HCA, IRQL %d\n", KeGetCurrentIrql()));\r
\r
+ /* get MLX4_BUS IB interface */\r
+ status = __get_ifc( p_dev_obj, &MLX4_BUS_IB_INTERFACE_GUID,\r
+ sizeof(MLX4_BUS_IB_INTERFACE), MLX4_BUS_IB_INTERFACE_VERSION, NULL, (PINTERFACE)&p_fdo->bus_ib_ifc);\r
+ if( !NT_SUCCESS( status ) ) {\r
+ HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("Getting MLX4 BUS interface failed: status=0x%x\n", status));\r
+ goto err_hca_reg;\r
+ }\r
+ p_fdo->bus_ib_ifc_taken = TRUE;\r
+ p_fdo->bus_ib_ifc.p_ibdev->x.p_fdo = p_fdo;\r
+\r
+ /* get node GUID */\r
+ err = __get_dev_info( p_fdo, &p_fdo->hca.guid, &p_fdo->hca.hw_ver );\r
+ if (err) {\r\r
+ HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,\r
+ ("can't get guid - ib_query_device() failed (%08X)\n", err ));\r
+ //TODO: no cleanup on error\r
+ goto err_hca_reg;\r
+ }\r
+\r
if( p_fdo->p_al_dev ) {\r
status = __hca_register( p_dev_obj );\r
if( !NT_SUCCESS( status ) ) {\r
\r
{\r
__hca_deregister( p_fdo );\r
+\r
+ // release MLX4_BUS resources\r
+ if(p_fdo->bus_ib_ifc_taken) {\r
+ p_fdo->bus_ib_ifc_taken = FALSE;\r
+ __put_ifc( (PINTERFACE)&p_fdo->bus_ib_ifc );\r
+ }\r
}\r
\r
IoCopyCurrentIrpStackLocationToNext( p_irp );\r