Commit 43ef4e04434e476a42e66e71597dc9982474975a

ckolivas 2012-03-29T10:51:59

Move the ADL setup and clearing to separate functions and provide a reinit_adl function to be used when adl fails while running.

diff --git a/adl.c b/adl.c
index 70dcdfe..13dd06b 100644
--- a/adl.c
+++ b/adl.c
@@ -124,11 +124,9 @@ static bool fanspeed_twin(struct gpu_adl *ga, struct gpu_adl *other_ga)
 	return true;
 }
 
-void init_adl(int nDevs)
+static bool prepare_adl(void)
 {
-	int result, i, j, devices = 0, last_adapter = -1, gpu = 0, dummy = 0;
-	struct gpu_adapters adapters[MAX_GPUDEVICES], vadapters[MAX_GPUDEVICES];
-	bool devs_match = true;
+	int result;
 
 #if defined (LINUX)
 	hDLL = dlopen( "libatiadlxx.so", RTLD_LAZY|RTLD_GLOBAL);
@@ -141,14 +139,8 @@ void init_adl(int nDevs)
 #endif
 	if (hDLL == NULL) {
 		applog(LOG_INFO, "Unable to load ati adl library");
-		return;
-	}
-
-	if (unlikely(pthread_mutex_init(&adl_lock, NULL))) {
-		applog(LOG_ERR, "Failed to init adl_lock in init_adl");
-		return;
+		return false;
 	}
-
 	ADL_Main_Control_Create = (ADL_MAIN_CONTROL_CREATE) GetProcAddress(hDLL,"ADL_Main_Control_Create");
 	ADL_Main_Control_Destroy = (ADL_MAIN_CONTROL_DESTROY) GetProcAddress(hDLL,"ADL_Main_Control_Destroy");
 	ADL_Adapter_NumberOfAdapters_Get = (ADL_ADAPTER_NUMBEROFADAPTERS_GET) GetProcAddress(hDLL,"ADL_Adapter_NumberOfAdapters_Get");
@@ -177,7 +169,7 @@ void init_adl(int nDevs)
 		!ADL_Main_Control_Refresh || !ADL_Overdrive5_PowerControl_Get ||
 		!ADL_Overdrive5_PowerControl_Set || !ADL_Overdrive5_FanSpeedToDefault_Set) {
 			applog(LOG_WARNING, "ATI ADL's API is missing");
-		return;
+		return false;
 	}
 
 	// Initialise ADL. The second parameter is 1, which means:
@@ -185,15 +177,32 @@ void init_adl(int nDevs)
 	result = ADL_Main_Control_Create (ADL_Main_Memory_Alloc, 1);
 	if (result != ADL_OK) {
 		applog(LOG_INFO, "ADL Initialisation Error! Error %d!", result);
-		return ;
+		return false;
 	}
 
 	result = ADL_Main_Control_Refresh();
 	if (result != ADL_OK) {
 		applog(LOG_INFO, "ADL Refresh Error! Error %d!", result);
-		return ;
+		return false;
 	}
 
+	return true;
+}
+
+void init_adl(int nDevs)
+{
+	int result, i, j, devices = 0, last_adapter = -1, gpu = 0, dummy = 0;
+	struct gpu_adapters adapters[MAX_GPUDEVICES], vadapters[MAX_GPUDEVICES];
+	bool devs_match = true;
+
+	if (unlikely(pthread_mutex_init(&adl_lock, NULL))) {
+		applog(LOG_ERR, "Failed to init adl_lock in init_adl");
+		return;
+	}
+
+	if (!prepare_adl())
+		return;
+
 	// Obtain the number of adapters for the system
 	result = ADL_Adapter_NumberOfAdapters_Get (&iNumberAdapters);
 	if (result != ADL_OK) {
@@ -1314,6 +1323,17 @@ updated:
 }
 #endif
 
+static void free_adl(void)
+{
+	ADL_Main_Memory_Free ((void **)&lpInfo);
+	ADL_Main_Control_Destroy ();
+#if defined (LINUX)
+	dlclose(hDLL);
+#else
+	FreeLibrary(hDLL);
+#endif
+}
+
 void clear_adl(int nDevs)
 {
 	struct gpu_adl *ga;
@@ -1334,15 +1354,21 @@ void clear_adl(int nDevs)
 		ADL_Overdrive5_FanSpeed_Set(ga->iAdapterIndex, 0, &ga->DefFanSpeedValue);
 		ADL_Overdrive5_FanSpeedToDefault_Set(ga->iAdapterIndex, 0);
 	}
-
-	ADL_Main_Memory_Free ( (void **)&lpInfo );
-	ADL_Main_Control_Destroy ();
+	adl_active = false;
 	unlock_adl();
+	free_adl();
+}
 
-#if defined (LINUX)
-	dlclose(hDLL);
-#else
-	FreeLibrary(hDLL);
-#endif
+void reinit_adl(void)
+{
+	bool ret;
+	lock_adl();
+	free_adl();
+	ret = prepare_adl();
+	if (!ret) {
+		adl_active = false;
+		applog(LOG_WARNING, "Attempt to re-initialise ADL has failed, disabling");
+	}
+	unlock_adl();
 }
 #endif /* HAVE_ADL */
diff --git a/adl.h b/adl.h
index f48c420..363741c 100644
--- a/adl.h
+++ b/adl.h
@@ -19,10 +19,12 @@ bool gpu_stats(int gpu, float *temp, int *engineclock, int *memclock, float *vdd
 void change_gpusettings(int gpu);
 void gpu_autotune(int gpu, enum dev_enable *denable);
 void clear_adl(int nDevs);
+void reinit_adl(void);
 #else /* HAVE_ADL */
 #define adl_active (0)
 static inline void init_adl(int nDevs) {}
 static inline void change_gpusettings(int gpu) { }
 static inline void clear_adl(int nDevs) {}
+static inline void reinit_adl(void) {}
 #endif
 #endif