Browse Source

Abstract ft232r scan+probe interface into new generic lowlevel driver interface

Luke Dashjr 12 years ago
parent
commit
24d4e7f256
8 changed files with 170 additions and 66 deletions
  1. 4 0
      Makefile.am
  2. 7 0
      configure.ac
  3. 41 56
      ft232r.c
  4. 0 2
      ft232r.h
  5. 75 0
      lowlevel.c
  6. 36 0
      lowlevel.h
  7. 6 8
      miner.c
  8. 1 0
      miner.h

+ 4 - 0
Makefile.am

@@ -177,6 +177,10 @@ bfgminer_SOURCES += iospeeds.h iospeeds_posix.h
 endif
 endif
 
+if NEED_BFG_LOWLEVEL
+bfgminer_SOURCES += lowlevel.c lowlevel.h
+endif
+
 if NEED_DYNCLOCK
 bfgminer_SOURCES += dynclock.c dynclock.h
 endif

+ 7 - 0
configure.ac

@@ -91,6 +91,7 @@ optlist=
 
 need_dynclock=no
 need_fpgautils=no
+need_lowlevel=no
 have_cygwin=false
 have_win32=false
 have_macho=false
@@ -482,6 +483,7 @@ if test "x$x6500" = xyes; then
 	AC_DEFINE([USE_X6500], [1], [Defined to 1 if X6500 support is wanted])
 	need_dynclock=yes
 	need_fpgautils=yes
+	need_lowlevel=yes
 fi
 AM_CONDITIONAL([HAS_X6500], [test x$x6500 = xyes])
 
@@ -637,6 +639,10 @@ if test x$need_fpgautils = xyes; then
 	fi
 fi
 
+if test x$need_lowlevel = xyes; then
+	AC_DEFINE([HAVE_BFG_LOWLEVEL], [1], [Defined to 1 if lowlevel drivers are being used])
+fi
+
 
 curses="auto"
 
@@ -790,6 +796,7 @@ AC_SUBST(libblkmaker_LIBS)
 AM_CONDITIONAL([NEED_LIBBLKMAKER], [test x$with_system_libblkmaker != xyes])
 AM_CONDITIONAL([NEED_DYNCLOCK], [test x$need_dynclock = xyes])
 AM_CONDITIONAL([NEED_FPGAUTILS], [test x$need_fpgautils = xyes])
+AM_CONDITIONAL([NEED_BFG_LOWLEVEL], [test x$need_lowlevel = xyes])
 AM_CONDITIONAL([HAS_SCRYPT], [test x$scrypt = xyes])
 AM_CONDITIONAL([HAVE_CURSES], [test x$curses = xyes])
 AM_CONDITIONAL([HAVE_SENSORS], [test x$with_sensors = xyes])

+ 41 - 56
ft232r.c

@@ -24,58 +24,40 @@
 #include "fpgautils.h"
 #include "ft232r.h"
 #include "logging.h"
+#include "lowlevel.h"
 #include "miner.h"
 
 #define FT232R_IDVENDOR   0x0403
 #define FT232R_IDPRODUCT  0x6001
 
-struct ft232r_device_info {
-	libusb_device *libusb_dev;
-	char *product;
-	char *serial;
-};
-
-static struct ft232r_device_info **ft232r_devinfo_list;
-
-void ft232r_scan_free()
+static
+void ft232r_devinfo_free(struct lowlevel_device_info * const info)
 {
-	if (!ft232r_devinfo_list)
-		return;
-
-	struct ft232r_device_info *info;
-
-	for (struct ft232r_device_info **infop = ft232r_devinfo_list; (info = *infop); ++infop) {
-		libusb_unref_device(info->libusb_dev);
-		free(info->product);
-		free(info->serial);
-		free(info);
-	}
-	free(ft232r_devinfo_list);
-	ft232r_devinfo_list = NULL;
+	libusb_unref_device(info->lowl_data);
 }
 
-void ft232r_scan()
+static
+struct lowlevel_device_info *ft232r_devinfo_scan()
 {
-	ssize_t count, n, i, found = 0;
+	struct lowlevel_device_info *devinfo_list = NULL;
+	ssize_t count, n, i;
 	libusb_device **list;
 	struct libusb_device_descriptor desc;
 	libusb_device_handle *handle;
-	struct ft232r_device_info *info;
+	struct lowlevel_device_info *info;
 	int err;
 	unsigned char buf[0x100];
 	int skipped = 0;
 
-	ft232r_scan_free();
-
+	if (unlikely(!have_libusb))
+		return NULL;
+	
 	count = libusb_get_device_list(NULL, &list);
 	if (unlikely(count < 0)) {
 		applog(LOG_ERR, "ft232r_scan: Error getting USB device list: %s", bfg_strerror(count, BST_LIBUSB));
-		ft232r_devinfo_list = calloc(1, sizeof(struct ft232r_device_info *));
-		return;
+		return NULL;
 	}
 
-	ft232r_devinfo_list = malloc(sizeof(struct ft232r_device_info *) * (count + 1));
-
 	for (i = 0; i < count; ++i) {
 		if (bfg_claim_libusb(NULL, false, list[i]))
 		{
@@ -106,7 +88,10 @@ void ft232r_scan()
 			continue;
 		}
 		buf[n] = '\0';
-		info = malloc(sizeof(struct ft232r_device_info));
+		info = malloc(sizeof(struct lowlevel_device_info));
+		*info = (struct lowlevel_device_info){
+			.lowl = &lowl_ft232r,
+		};
 		info->product = strdup((char*)buf);
 
 		n = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buf, sizeof(buf)-1);
@@ -117,42 +102,37 @@ void ft232r_scan()
 		}
 		buf[n] = '\0';
 		info->serial = strdup((char*)buf);
-		info->libusb_dev = libusb_ref_device(list[i]);
-		ft232r_devinfo_list[found++] = info;
+		info->lowl_data = libusb_ref_device(list[i]);
+		
+		LL_PREPEND(devinfo_list, info);
 
 		applog(LOG_DEBUG, "ft232r_scan: Found \"%s\" serial \"%s\"", info->product, info->serial);
 	}
 
-	ft232r_devinfo_list[found] = NULL;
 	libusb_free_device_list(list, 1);
 	
 	if (skipped)
 		applog(LOG_DEBUG, "%s: Skipping probe of %d claimed devices", __func__, skipped);
+	
+	return devinfo_list;
 }
 
-int ft232r_detect(const char *product_needle, const char *serial, foundusb_func_t cb)
+static foundusb_func_t _wrapper_cb;
+static
+bool _wrapper(struct lowlevel_device_info *info)
 {
-	struct ft232r_device_info *info;
-	int found = 0;
-
-	for (struct ft232r_device_info **infop = ft232r_devinfo_list; (info = *infop); ++infop) {
-		if (serial) {
-			// If we are searching for a specific serial, pay no attention to the product id
-			if (strcmp(serial, info->serial))
-				continue;
-		}
-		else
-		if (!strstr(info->product, product_needle))
-			continue;
-		if (!info->libusb_dev)
-			continue;
-		if (!cb(info->libusb_dev, info->product, info->serial))
-			continue;
-		info->libusb_dev = NULL;
-		++found;
-	}
+	if (info->lowl != &lowl_ft232r)
+		return false;
+	return _wrapper_cb(info->lowl_data, info->product, info->serial);
+}
 
-	return found;
+int ft232r_detect(const char *product_needle, const char *serial, foundusb_func_t cb)
+{
+	_wrapper_cb = cb;
+	if (serial)
+		return lowlevel_detect_serial(_wrapper, serial);
+	else
+		return lowlevel_detect(_wrapper, product_needle);
 }
 
 #define FTDI_REQTYPE  (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE)
@@ -408,6 +388,11 @@ bool ft232r_get_cbus_bits(struct ft232r_device_handle *dev, bool *out_sio0, bool
 	return true;
 }
 
+struct lowlevel_driver lowl_ft232r = {
+	.devinfo_scan = ft232r_devinfo_scan,
+	.devinfo_free = ft232r_devinfo_free,
+};
+
 #if 0
 int main() {
 	libusb_init(NULL);

+ 0 - 2
ft232r.h

@@ -25,8 +25,6 @@ struct ft232r_device_handle;
 
 typedef bool(*foundusb_func_t)(libusb_device *, const char *product, const char *serial);
 
-extern void ft232r_scan();
-extern void ft232r_scan_free();
 extern int ft232r_detect(const char *product_needle, const char *serial, foundusb_func_t);
 extern struct ft232r_device_handle *ft232r_open(libusb_device *);
 extern void ft232r_close(struct ft232r_device_handle *);

+ 75 - 0
lowlevel.c

@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012-2013 Luke Dashjr
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.  See COPYING for more details.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <utlist.h>
+
+#include "lowlevel.h"
+
+static struct lowlevel_device_info *devinfo_list;
+
+void lowlevel_devinfo_free(struct lowlevel_device_info * const info)
+{
+	info->lowl->devinfo_free(info);
+	free(info->product);
+	free(info->serial);
+	free(info);
+}
+
+void lowlevel_scan_free()
+{
+	if (!devinfo_list)
+		return;
+	
+	struct lowlevel_device_info *info, *tmp;
+	
+	LL_FOREACH_SAFE(devinfo_list, info, tmp)
+	{
+		LL_DELETE(devinfo_list, info);
+		lowlevel_devinfo_free(info);
+	}
+}
+
+void lowlevel_scan()
+{
+	struct lowlevel_device_info *devinfo_mid_list;
+	
+	lowlevel_scan_free();
+	
+#ifdef USE_X6500
+	devinfo_mid_list = lowl_ft232r.devinfo_scan();
+	LL_CONCAT(devinfo_list, devinfo_mid_list);
+#endif
+}
+
+int _lowlevel_detect(lowl_found_devinfo_func_t cb, const char *serial, const char **product_needles)
+{
+	struct lowlevel_device_info *info, *tmp;
+	int found = 0, i;
+	
+	LL_FOREACH_SAFE(devinfo_list, info, tmp)
+	{
+		if (serial && strcmp(serial, info->serial))
+			continue;
+		for (i = 0; product_needles[i]; ++i)
+			if (!strstr(info->product, product_needles[i]))
+				goto next;
+		if (!cb(info))
+			continue;
+		LL_DELETE(devinfo_list, info);
+		++found;
+next: ;
+	}
+	
+	return found;
+}

+ 36 - 0
lowlevel.h

@@ -0,0 +1,36 @@
+#ifndef _BFG_LOWLEVEL_H
+#define _BFG_LOWLEVEL_H
+
+#include <stdbool.h>
+
+struct lowlevel_device_info;
+
+typedef bool (*lowl_found_devinfo_func_t)(struct lowlevel_device_info *);
+
+struct lowlevel_driver {
+	struct lowlevel_device_info *(*devinfo_scan)();
+	void (*devinfo_free)(struct lowlevel_device_info *);
+};
+
+struct lowlevel_device_info {
+	char *product;
+	char *serial;
+	
+	struct lowlevel_driver *lowl;
+	void *lowl_data;
+	
+	struct lowlevel_device_info *next;
+};
+
+extern void lowlevel_scan();
+extern int _lowlevel_detect(lowl_found_devinfo_func_t, const char *serial, const char **product_needles);
+#define lowlevel_detect(func, ...)  _lowlevel_detect(func, NULL, (const char *[]){__VA_ARGS__, NULL})
+#define lowlevel_detect_serial(func, serial)  _lowlevel_detect(func, serial, (const char *[]){NULL})
+extern void lowlevel_scan_free();
+extern void lowlevel_devinfo_free(struct lowlevel_device_info *);
+
+#ifdef USE_X6500
+extern struct lowlevel_driver lowl_ft232r;
+#endif
+
+#endif

+ 6 - 8
miner.c

@@ -77,8 +77,8 @@
 #include "driver-avalon.h"
 #endif
 
-#ifdef USE_X6500
-#include "ft232r.h"
+#ifdef HAVE_BFG_LOWLEVEL
+#include "lowlevel.h"
 #endif
 
 #if defined(unix) || defined(__APPLE__)
@@ -9812,9 +9812,8 @@ extern struct sigaction pcwm_orig_term_handler;
 static
 void drv_detect_all()
 {
-#ifdef USE_X6500
-	if (likely(have_libusb))
-		ft232r_scan();
+#ifdef HAVE_BFG_LOWLEVEL
+	lowlevel_scan();
 #endif
 
 #ifdef USE_ICARUS
@@ -9880,9 +9879,8 @@ void drv_detect_all()
 	cpu_drv.drv_detect();
 #endif
 
-#ifdef USE_X6500
-	if (likely(have_libusb))
-		ft232r_scan_free();
+#ifdef HAVE_BFG_LOWLEVEL
+	lowlevel_scan_free();
 #endif
 
 #ifdef HAVE_OPENCL

+ 1 - 0
miner.h

@@ -903,6 +903,7 @@ extern bool opt_fail_only;
 extern bool opt_autofan;
 extern bool opt_autoengine;
 extern bool use_curses;
+extern bool have_libusb;
 extern int httpsrv_port;
 extern int stratumsrv_port;
 extern char *opt_api_allow;