*/\r
uint32_t g_mthca_dbg_level = TRACE_LEVEL_INFORMATION;\r
uint32_t g_mthca_dbg_flags= 0xffff;\r
-WCHAR g_wlog_buf[ MAX_LOG_BUF_LEN ]; \r
-UCHAR g_slog_buf[ MAX_LOG_BUF_LEN ]; \r
+WCHAR g_wlog_buf[ MAX_LOG_BUF_LEN ];\r
+UCHAR g_slog_buf[ MAX_LOG_BUF_LEN ];\r
+uint32_t g_skip_tavor_reset=0; /* skip reset for Tavor cards */\r
+uint32_t g_disable_tavor_reset=1; /* disable Tavor reset for the next driver load */\r
+UNICODE_STRING g_param_path;\r
+\r
\r
/*\r
* UVP name does not include file extension. For debug builds, UAL\r
{\r
NTSTATUS status;\r
/* Remember the terminating entry in the table below. */\r
- RTL_QUERY_REGISTRY_TABLE table[3];\r
- UNICODE_STRING param_path;\r
+ RTL_QUERY_REGISTRY_TABLE table[5];\r
\r
HCA_ENTER( HCA_DBG_DEV );\r
\r
- RtlInitUnicodeString( ¶m_path, NULL );\r
- param_path.MaximumLength = p_registry_path->Length + \r
+ RtlInitUnicodeString( &g_param_path, NULL );\r
+ g_param_path.MaximumLength = p_registry_path->Length + \r
sizeof(L"\\Parameters");\r
- param_path.Buffer = cl_zalloc( param_path.MaximumLength );\r
- if( !param_path.Buffer )\r
+ g_param_path.Buffer = cl_zalloc( g_param_path.MaximumLength );\r
+ if( !g_param_path.Buffer )\r
{\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_DEV, \r
+ HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_INIT, \r
("Failed to allocate parameters path buffer.\n"));\r
return STATUS_INSUFFICIENT_RESOURCES;\r
}\r
\r
- RtlAppendUnicodeStringToString( ¶m_path, p_registry_path );\r
- RtlAppendUnicodeToString( ¶m_path, L"\\Parameters" );\r
+ RtlAppendUnicodeStringToString( &g_param_path, p_registry_path );\r
+ RtlAppendUnicodeToString( &g_param_path, L"\\Parameters" );\r
\r
/*\r
* Clear the table. This clears all the query callback pointers,\r
table[1].DefaultData = &g_mthca_dbg_flags;\r
table[1].DefaultLength = sizeof(ULONG);\r
\r
+ table[2].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+ table[2].Name = L"SkipTavorReset";\r
+ table[2].EntryContext = &g_skip_tavor_reset;\r
+ table[2].DefaultType = REG_DWORD;\r
+ table[2].DefaultData = &g_skip_tavor_reset;\r
+ table[2].DefaultLength = sizeof(ULONG);\r
+\r
+ table[3].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+ table[3].Name = L"DisableTavorResetOnFailure";\r
+ table[3].EntryContext = &g_disable_tavor_reset;\r
+ table[3].DefaultType = REG_DWORD;\r
+ table[3].DefaultData = &g_disable_tavor_reset;\r
+ table[3].DefaultLength = sizeof(ULONG);\r
+\r
/* Have at it! */\r
status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
- param_path.Buffer, table, NULL, NULL );\r
+ g_param_path.Buffer, table, NULL, NULL );\r
\r
HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_INIT, \r
- ("debug level %d debug flags 0x%.8x\n",\r
- g_mthca_dbg_level ,\r
- g_mthca_dbg_flags));\r
-\r
+ ("debug level %d debug flags 0x%.8x SkipTavorReset %d DisableTavorReset %d\n",\r
+ g_mthca_dbg_level , g_mthca_dbg_flags,\r
+ g_skip_tavor_reset, g_disable_tavor_reset ));\r
\r
- cl_free( param_path.Buffer );\r
HCA_EXIT( HCA_DBG_DEV );\r
return status;\r
}\r
\r
+void set_skip_tavor_reset()\r
+{\r
+ NTSTATUS status;\r
+ HANDLE key_handle;\r
+ UNICODE_STRING key_name;\r
+ ULONG val = 1;\r
+ OBJECT_ATTRIBUTES oa;\r
+\r
+ HCA_ENTER( HCA_DBG_DEV );\r
+\r
+ InitializeObjectAttributes( &oa, &g_param_path, \r
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL );\r
+\r
+\r
+ status = ZwOpenKey( &key_handle, GENERIC_WRITE, &oa );\r
+ if( !NT_SUCCESS( status ) ) {\r
+ HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_LOW, \r
+ ("ZwOpenKey failed (%#x)\n", status));\r
+ goto err_open_key;\r
+ }\r
+\r
+ RtlInitUnicodeString( &key_name, L"SkipTavorReset" );\r
+ status = ZwSetValueKey( key_handle, &key_name, 0, \r
+ REG_DWORD, &val, sizeof(ULONG) );\r
+ if( !NT_SUCCESS( status ) ) {\r
+ HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_LOW, \r
+ ("ZwSetValueKey failed (%#x)\n", status));\r
+ }\r
+\r
+ ZwClose( key_handle );\r
+\r
+err_open_key:\r
+ HCA_EXIT( HCA_DBG_DEV );\r
+}\r
\r
static void\r
hca_drv_unload(\r
\r
ib_uverbs_cleanup();\r
ib_core_cleanup();\r
+ cl_free( g_param_path.Buffer );\r
\r
HCA_EXIT( HCA_DBG_DEV );\r
#if defined(EVENT_TRACING)\r
\r
HCA_ENTER( HCA_DBG_PNP );\r
\r
+ /* sanity check */\r
+ if (is_tavor && g_skip_tavor_reset) {\r
+ HCA_PRINT(TRACE_LEVEL_WARNING ,HCA_DBG_PNP ,("Card reset is skipped, trying to proceed.\n"));\r
+ goto resetExit;\r
+ }\r
+\r
/* get the resources */\r
{\r
/* Get the HCA's bus interface. */\r
status = __get_bus_ifc( pDevObj, &GUID_BUS_INTERFACE_STANDARD, &hcaBusIfc );\r
if( !NT_SUCCESS( status ) ) {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Failed to get HCA bus interface.\n"));\r
+ HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Failed to get HCA bus interface.\n"));\r
goto resetErr1;\r
}\r
\r
\r
/* Read the configuration register until it doesn't return 0xFFFFFFFF */\r
{\r
- ULONG data, i;\r
+ ULONG data, i, reset_failed = 1;\r
BUS_INTERFACE_STANDARD *p_ifc = (is_tavor) ? &brBusIfc : &hcaBusIfc;\r
HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Read the configuration register \n"));\r
for( i = 0; i < 100; i++ ) {\r
if (4 != p_ifc->GetBusData( p_ifc->Context,\r
PCI_WHICHSPACE_CONFIG, &data, 0, 4)) {\r
HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("Failed to read device configuration data.\n"));\r
+ ("Failed to read device configuration data. Card reset failed !\n"));\r
status = STATUS_UNSUCCESSFUL;\r
- goto resetErr3;\r
+ break;\r
}\r
/* See if we got valid data. */\r
- if( data != 0xFFFFFFFF )\r
- goto good;\r
+ if( data != 0xFFFFFFFF ) {\r
+ reset_failed = 0;\r
+ break;\r
+ }\r
\r
cl_thread_suspend( 100 );\r
} \r
\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("Doh! PCI device did not come back after reset!\n"));\r
- status = STATUS_UNSUCCESSFUL;\r
- goto resetErr3;\r
+ if (reset_failed) {\r
+ /* on Tavor reset failure, if configured so, we disable the reset for next time */\r
+ if (is_tavor && g_disable_tavor_reset)\r
+ set_skip_tavor_reset();\r
+\r
+ HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
+ ("Doh! PCI device did not come back after reset!\n"));\r
+ status = STATUS_UNSUCCESSFUL;\r
+ goto resetErr3;\r
+ }\r
}\r
\r
-good: /* restore the HCA's PCI configuration headers */\r
+ /* restore the HCA's PCI configuration headers */\r
{\r
if (is_tavor) {\r
/* Restore the HCA's bridge configuration. */\r
status = __restore_pci_config( &brBusIfc, &brConfig, TRUE );\r
if( !NT_SUCCESS( status ) ) {\r
HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("Failed to restore bridge config.\n"));\r
+ ("Failed to restore bridge config. Card reset failed !\n"));\r
goto resetErr3;\r
}\r
}\r
status = __restore_pci_config( &hcaBusIfc, &hcaConfig, FALSE );\r
if( !NT_SUCCESS( status ) ) {\r
HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("Failed to restore HCA config.\n"));\r
+ ("Failed to restore HCA config. Card reset failed !\n"));\r
}\r
}\r
\r
hcaBusIfc.InterfaceDereference( hcaBusIfc.Context );\r
\r
resetErr1:\r
+resetExit:\r
HCA_EXIT( HCA_DBG_PNP );\r
return status;\r
}\r