}\r
#endif\r
\r
+#if 1//WORKAROUND_POLL_EQ\r
+\r
+BOOLEAN\r
+IsrSynchronizeRoutine(\r
+ IN PVOID SynchronizeContext\r
+ )\r
+{\r
+ struct mthca_dev *dev = (struct mthca_dev *)SynchronizeContext;\r
+\r
+ //Is this always correct?\r
+ mthca_arbel_interrupt(dev->ext->int_obj,dev);\r
+ \r
+ return TRUE;\r
+}\r
+\r
+\r
+VOID eq_polling_thread(void *ctx) \r
+{\r
+#define POLLING_INTERVAL_MS 50\r
+ NTSTATUS status;\r
+ struct mthca_dev *dev = (struct mthca_dev *)ctx;\r
+ PVOID wait_objects[2];\r
+ LARGE_INTEGER wait_time;\r
+\r
+ wait_objects[0] = &dev->eq_table.thread_stop_event;\r
+ wait_objects[1] = &dev->eq_table.thread_start_event;\r
+\r
+ for(;;){\r
+\r
+ /* before start polling */\r
+ DbgPrint("Before polling.\n");\r
+ for (;;) {\r
+ status = KeWaitForMultipleObjects( 2, wait_objects, \r
+ WaitAny, Executive, KernelMode, FALSE, NULL, NULL );\r
+\r
+ if ( status == STATUS_WAIT_0 ){/* thread stopped */\r
+ DbgPrint("Signaled to stop polling.\n");\r
+ break; \r
+ }\r
+\r
+ /* start polling */\r
+ if ( status == STATUS_WAIT_1 ){\r
+ DbgPrint("Signaled to start polling.\n");\r
+ break; \r
+ }\r
+\r
+ }\r
+\r
+ if(dev->eq_table.bTerminated) break;\r
+ if ( status == STATUS_WAIT_0 ) continue;/* thread stopped, wait for start again */\r
+\r
+ /* polling */\r
+ DbgPrint("Start polling.\n");\r
+ wait_time.QuadPart = -(int64_t)(((uint64_t)POLLING_INTERVAL_MS) * 10000);\r
+ for (;;) {\r
+ //mlx4_interrupt( NULL, &priv->dev );\r
+ KeSynchronizeExecution(dev->ext->int_obj, IsrSynchronizeRoutine, dev);\r
+\r
+ status = KeWaitForSingleObject( &dev->eq_table.thread_stop_event, \r
+ Executive, KernelMode, FALSE, &wait_time );\r
+ if ( status == STATUS_SUCCESS ) {\r
+ //KeClearEvent(&priv->eq_table.thread_stop_event);\r
+ DbgPrint("Signaled to stop polling while in polling mode.\n");\r
+ break; /* thread stopped */\r
+ }\r
+ }\r
+\r
+ if(dev->eq_table.bTerminated) break;\r
+ }\r
+\r
+ DbgPrint("Polling thread terminated.\n");\r
+ PsTerminateSystemThread(STATUS_SUCCESS);\r
+\r
+}\r
+\r
+\r
+void mlnx_poll_eq(struct ib_device *device, BOOLEAN bStart)\r
+{\r
+ LONG signalled=0;\r
+ struct mthca_dev *dev = (struct mthca_dev *)(device);\r
+\r
+ if(bStart){\r
+ /* signal start of polling */\r
+ signalled = KeSetEvent( \r
+ &dev->eq_table.thread_start_event, IO_NO_INCREMENT, FALSE );\r
+ }else{\r
+ /* signal end of polling */\r
+ signalled = KeSetEvent( \r
+ &dev->eq_table.thread_stop_event, IO_NO_INCREMENT, FALSE );\r
+ }\r
+\r
+}\r
+\r
+#endif\r
+\r
static int mthca_create_eq(struct mthca_dev *dev,\r
int nent,\r
u8 intr,\r
else\r
tavor_eq_req_not(dev, dev->eq_table.eq[i].eqn);\r
\r
+#if 1//WORKAROUND_POLL_EQ\r
+ { /* Create a thread for polling EQs in case of missing interrupts from the card */\r
+ NTSTATUS status;\r
+ OBJECT_ATTRIBUTES attr;\r
+ HANDLE handle;\r
+\r
+ KeInitializeEvent(&dev->eq_table.thread_start_event, SynchronizationEvent, FALSE);\r
+ KeInitializeEvent(&dev->eq_table.thread_stop_event, SynchronizationEvent, FALSE);\r
+ dev->eq_table.bTerminated = FALSE;\r
+ dev->eq_table.threadObject = NULL;\r
+ InitializeObjectAttributes( &attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );\r
+ status = PsCreateSystemThread( &handle, \r
+ THREAD_ALL_ACCESS, &attr, NULL, NULL, eq_polling_thread, dev );\r
+ if (NT_SUCCESS(status)) {\r
+ status = ObReferenceObjectByHandle(\r
+ handle,\r
+ THREAD_ALL_ACCESS,\r
+ NULL,\r
+ KernelMode,\r
+ &dev->eq_table.threadObject,\r
+ NULL\r
+ );\r
+\r
+ ASSERT(status == STATUS_SUCCESS); //\r
+\r
+ status = ZwClose(handle);\r
+\r
+ ASSERT(NT_SUCCESS(status)); // Should always succeed\r
+\r
+ }\r
+ }\r
+#endif\r
+\r
return 0;\r
\r
err_out_cmd:\r
u8 status;\r
int i;\r
\r
+#if 1//WORKAROUND_POLL_EQ\r
+ /* stop the EQ polling thread */\r
+ if (dev->eq_table.threadObject) { \r
+ #define WAIT_TIME_MS 3000\r
+ NTSTATUS status;\r
+ LARGE_INTEGER wait_time;\r
+ LONG signalled;\r
+\r
+ dev->eq_table.bTerminated = TRUE;\r
+\r
+ /* signal polling stopped in case it is not */\r
+ signalled = KeSetEvent( \r
+ &dev->eq_table.thread_stop_event, IO_NO_INCREMENT, FALSE );\r
+\r
+ /* wait for completion of the thread */\r
+ wait_time.QuadPart = -(int64_t)(((uint64_t)WAIT_TIME_MS) * 10000);\r
+ status = KeWaitForSingleObject( dev->eq_table.threadObject,\r
+ Executive, KernelMode, FALSE, &wait_time );\r
+ ASSERT(status == STATUS_SUCCESS);\r
+\r
+ ObDereferenceObject(dev->eq_table.threadObject);\r
+\r
+ /* cleanup */\r
+ dev->eq_table.threadObject = NULL;\r
+ }\r
+#endif\r
+\r
mthca_free_irqs(dev);\r
\r
mthca_MAP_EQ(dev, async_mask(dev),\r