Hi,

Recently I tried using several usbasp compatible programmers (running my
reimplemantation of the usbasp protocol[1]) at the same time, unfortunately
it is impossible to tell avrdude which one to use (it will just the first it
discovers, and I ended up using a usbasp programmer and my old avrisp2. *brr*).

So I added a unique usb serial number to all of my programmer devices and
patched avrdude so that if the port (-P) is given in the format usb:serialno
(like in the stk500v2 module), only devices with (prefix-) matching serial
numbers are considered.

It would be great if you could either integrate my patch into avrdude or
tell me why the patch is rejected (so I can amend).

Cheers,
- Alexander

[1] http://github.com/fd0/kahuna
From 2118396ea6ee27a814973bf2dd1a4960d7612ed5 Mon Sep 17 00:00:00 2001
From: Alexander Neumann <[email protected]>
Date: Sun, 19 Sep 2010 02:26:45 +0200
Subject: [PATCH 1/2] match serial number for usbasp-compatible programmers

when using an usbasp compatible programmer, it is now possible to
specify the serial number of the desired programmer device using
    -P usb:serialno
---
 avrdude.1 |    7 ++
 usbasp.c  |  192 ++++++++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 148 insertions(+), 51 deletions(-)

diff --git a/avrdude.1 b/avrdude.1
index 3da8b55..0e13623 100644
--- a/avrdude.1
+++ b/avrdude.1
@@ -505,6 +505,13 @@ from the serial number need to be given.
 As the AVRISP mkII device can only be talked to over USB, the very
 same method of specifying the port is required there.
 .Pp
+For programmers using the "USBasp" protocol, the port can be specified as
+.Pa usb Ns Op \&: Ns Ar serialno .
+If
+.Ar serialno
+is specified, only devices with matching usb serial number strings (case
+insensitive) will be considered.
+.Pp
 For the USB programmer "AVR-Doper" running in HID mode, the port must
 be specified as
 .Ar avrdoper.
diff --git a/usbasp.c b/usbasp.c
index c8ae501..343158f 100644
--- a/usbasp.c
+++ b/usbasp.c
@@ -174,7 +174,7 @@ static int usbasp_transmit(PROGRAMMER * pgm,
  */
 #ifdef USE_LIBUSB_1_0
 static int usbOpenDevice(libusb_device_handle **device, int vendor,
-			 char *vendorName, int product, char *productName)
+			 char *vendorName, int product, char *productName, char *serialNumber)
 {
     libusb_device_handle *handle = NULL;
     int                  errorCode = USB_ERROR_NOTFOUND;
@@ -205,13 +205,15 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
 			    progname, strerror(libusb_to_errno(r)));
                     continue;
                 }
-                if (vendorName == NULL && productName == NULL) {
+
+                if(vendorName == NULL){
 		    /* name does not matter */
                     break;
                 }
                 /* now check whether the names match: */
-		r = libusb_get_string_descriptor_ascii(handle, descriptor.iManufacturer & 0xff, string, sizeof(string));
-                if (r < 0) {
+		r = libusb_get_string_descriptor_ascii(handle, descriptor.iManufacturer & 0xff,
+		                                       string, sizeof(string));
+                if(r < 0){
                     errorCode = USB_ERROR_IO;
                     fprintf(stderr,
 			    "%s: Warning: cannot query manufacturer for device: %s\n",
@@ -222,26 +224,65 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
 		        fprintf(stderr,
 				"%s: seen device from vendor ->%s<-\n",
 				progname, string);
-                    if (strcmp(string, vendorName) == 0){
-			r = libusb_get_string_descriptor_ascii(handle, descriptor.iProduct & 0xff, string, sizeof(string));
-                        if (r < 0) {
-                            errorCode = USB_ERROR_IO;
-                            fprintf(stderr,
-				    "%s: Warning: cannot query product for device: %s\n",
-				    progname, strerror(libusb_to_errno(r)));
-                        } else {
-                            errorCode = USB_ERROR_NOTFOUND;
-			    if (verbose > 1)
-			        fprintf(stderr,
-					"%s: seen product ->%s<-\n",
-					progname, string);
-                            if(strcmp(string, productName) == 0)
-                                break;
-                        }
+                    if(strcmp(string, vendorName) != 0){
+                        /* vendor name does not match, close handle and continue */
+                        usb_close(handle);
+                        handle = NULL;
+                        continue;
+                    }
+                }
+
+                if(productName == NULL){
+		    /* name does not matter */
+                    break;
+                }
+                /* now check whether the names match: */
+		r = libusb_get_string_descriptor_ascii(handle, descriptor.iProduct & 0xff,
+		                                       string, sizeof(string));
+                if(r < 0){
+                    errorCode = USB_ERROR_IO;
+                    fprintf(stderr,
+			    "%s: Warning: cannot query product for device: %s\n",
+			    progname, strerror(libusb_to_errno(r)));
+                }else{
+                    errorCode = USB_ERROR_NOTFOUND;
+		    if (verbose > 1)
+		        fprintf(stderr,
+				"%s: seen product ->%s<-\n",
+				progname, string);
+                    if(strcmp(string, productName) != 0){
+                        /* product name does not match, close handle and continue */
+                        usb_close(handle);
+                        handle = NULL;
+                        continue;
+                    }
+                }
+
+                if (serialNumber == NULL){
+                    /* serial number does not matter */
+                    break;
+                }
+                /* now check whether the names match: */
+		r = libusb_get_string_descriptor_ascii(handle, descriptor.iSerialNumber & 0xff,
+		                                       string, sizeof(string));
+                if(r < 0){
+                    errorCode = USB_ERROR_IO;
+                    fprintf(stderr,
+			    "%s: Warning: cannot query serial number for device: %s\n",
+			    progname, strerror(libusb_to_errno(r)));
+                }else{
+                    errorCode = USB_ERROR_NOTFOUND;
+		    if (verbose > 1)
+		        fprintf(stderr,
+				"%s: seen serial number ->%s<-\n",
+				progname, string);
+                    if(strcasecmp(string, serialNumber) != 0){
+                        /* serial number does not match, close handle and continue */
+                        usb_close(handle);
+                        handle = NULL;
+                        continue;
                     }
                 }
-                libusb_close(handle);
-                handle = NULL;
             }
     }
     if (handle != NULL){
@@ -252,7 +293,7 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
 }
 #else
 static int usbOpenDevice(usb_dev_handle **device, int vendor,
-			 char *vendorName, int product, char *productName)
+			 char *vendorName, int product, char *productName, char *serialNumber)
 {
 struct usb_bus       *bus;
 struct usb_device    *dev;
@@ -281,7 +322,7 @@ static int           didUsbInit = 0;
 			    progname, usb_strerror());
                     continue;
                 }
-                if(vendorName == NULL && productName == NULL){
+                if(vendorName == NULL){
 		    /* name does not matter */
                     break;
                 }
@@ -299,27 +340,65 @@ static int           didUsbInit = 0;
 		        fprintf(stderr,
 				"%s: seen device from vendor ->%s<-\n",
 				progname, string);
-                    if(strcmp(string, vendorName) == 0){
-                        len = usb_get_string_simple(handle, dev->descriptor.iProduct,
-						    string, sizeof(string));
-                        if(len < 0){
-                            errorCode = USB_ERROR_IO;
-                            fprintf(stderr,
-				    "%s: Warning: cannot query product for device: %s\n",
-				    progname, usb_strerror());
-                        }else{
-                            errorCode = USB_ERROR_NOTFOUND;
-			    if (verbose > 1)
-			        fprintf(stderr,
-					"%s: seen product ->%s<-\n",
-					progname, string);
-                            if(strcmp(string, productName) == 0)
-                                break;
-                        }
+                    if(strcmp(string, vendorName) != 0){
+                        /* vendor name does not match, close handle and continue */
+                        usb_close(handle);
+                        handle = NULL;
+                        continue;
+                    }
+                }
+
+                if(productName == NULL){
+		    /* name does not matter */
+                    break;
+                }
+                /* now check whether the names match: */
+                len = usb_get_string_simple(handle, dev->descriptor.iProduct,
+					    string, sizeof(string));
+                if(len < 0){
+                    errorCode = USB_ERROR_IO;
+                    fprintf(stderr,
+			    "%s: Warning: cannot query product for device: %s\n",
+			    progname, usb_strerror());
+                }else{
+                    errorCode = USB_ERROR_NOTFOUND;
+		    if (verbose > 1)
+		        fprintf(stderr,
+				"%s: seen product ->%s<-\n",
+				progname, string);
+                    if(strcmp(string, productName) != 0){
+                        /* product name does not match, close handle and continue */
+                        usb_close(handle);
+                        handle = NULL;
+                        continue;
+                    }
+                }
+
+                if (serialNumber == NULL){
+                    /* serial number does not matter */
+                    break;
+                }
+                /* now check whether the names match: */
+                len = usb_get_string_simple(handle, dev->descriptor.iSerialNumber,
+					    string, sizeof(string));
+                if(len < 0){
+                    errorCode = USB_ERROR_IO;
+                    fprintf(stderr,
+			    "%s: Warning: cannot query serial number for device: %s\n",
+			    progname, usb_strerror());
+                }else{
+                    errorCode = USB_ERROR_NOTFOUND;
+		    if (verbose > 1)
+		        fprintf(stderr,
+				"%s: seen serial number ->%s<-\n",
+				progname, string);
+                    if(strcasecmp(string, serialNumber) != 0){
+                        /* serial number does not match, close handle and continue */
+                        usb_close(handle);
+                        handle = NULL;
+                        continue;
                     }
                 }
-                usb_close(handle);
-                handle = NULL;
             }
         }
         if(handle)
@@ -340,28 +419,39 @@ static int usbasp_open(PROGRAMMER * pgm, char * port)
 #else
   usb_init();
 #endif
-  if(strcasecmp(port, "nibobee") == 0) {
+
+  /* save serial port in PROGRAMMER struct */
+  strcpy(pgm->port, port);
+
+  /* if serial number has been specified, remember pointer */
+  char *usbSerialNumber = NULL;
+  if (strncasecmp(pgm->port, "usb:", 4) == 0)
+      usbSerialNumber = &pgm->port[4];
+  if (strncasecmp(pgm->port, "nibobee:", 8) == 0)
+      usbSerialNumber = &pgm->port[8];
+
+  if(strncasecmp(port, "nibobee", 7) == 0) {
     if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_NIBOBEE_VID, "www.nicai-systems.com",
-		    USBASP_NIBOBEE_PID, "NIBObee") != 0) {
+		    USBASP_NIBOBEE_PID, "NIBObee", usbSerialNumber) != 0) {
       fprintf(stderr,
 	      "%s: error: could not find USB device "
-	      "\"NIBObee\" with vid=0x%x pid=0x%x\n",
-  	      progname, USBASP_NIBOBEE_VID, USBASP_NIBOBEE_PID);
+	      "\"NIBObee\" with vid=0x%x pid=0x%x serial=%s\n",
+  	      progname, USBASP_NIBOBEE_VID, USBASP_NIBOBEE_PID, usbSerialNumber);
       return -1;
       
     }
   } else if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_SHARED_VID, "www.fischl.de",
-		    USBASP_SHARED_PID, "USBasp") != 0) {
+		    USBASP_SHARED_PID, "USBasp", usbSerialNumber) != 0) {
 
     /* check if device with old VID/PID is available */
     if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de",
-		      USBASP_OLD_PID, "USBasp") != 0) {
+		      USBASP_OLD_PID, "USBasp", usbSerialNumber) != 0) {
 
       /* no USBasp found */
       fprintf(stderr,
 	      "%s: error: could not find USB device "
-	      "\"USBasp\" with vid=0x%x pid=0x%x\n",
-  	      progname, USBASP_SHARED_VID, USBASP_SHARED_PID);
+	      "\"USBasp\" with vid=0x%x pid=0x%x serial=%s\n",
+  	      progname, USBASP_SHARED_VID, USBASP_SHARED_PID, usbSerialNumber);
       return -1;
 
     } else {
-- 
1.7.1

From 8f6183e9fd179d8a089ed5731d4c949e5f4e59c1 Mon Sep 17 00:00:00 2001
From: Alexander Neumann <[email protected]>
Date: Sun, 19 Sep 2010 02:34:31 +0200
Subject: [PATCH 2/2] prefix matching for usb serial numbers (for usbasp)

---
 avrdude.1 |    4 +++-
 usbasp.c  |    4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/avrdude.1 b/avrdude.1
index 0e13623..2916767 100644
--- a/avrdude.1
+++ b/avrdude.1
@@ -510,7 +510,9 @@ For programmers using the "USBasp" protocol, the port can be specified as
 If
 .Ar serialno
 is specified, only devices with matching usb serial number strings (case
-insensitive) will be considered.
+insensitive) will be considered.  It is sufficient if the device's usb serial
+number is a prefix of
+.Ar serialno .
 .Pp
 For the USB programmer "AVR-Doper" running in HID mode, the port must
 be specified as
diff --git a/usbasp.c b/usbasp.c
index 343158f..14beffe 100644
--- a/usbasp.c
+++ b/usbasp.c
@@ -276,7 +276,7 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
 		        fprintf(stderr,
 				"%s: seen serial number ->%s<-\n",
 				progname, string);
-                    if(strcasecmp(string, serialNumber) != 0){
+                    if(strncasecmp(string, serialNumber, strlen(serialNumber)) != 0){
                         /* serial number does not match, close handle and continue */
                         usb_close(handle);
                         handle = NULL;
@@ -392,7 +392,7 @@ static int           didUsbInit = 0;
 		        fprintf(stderr,
 				"%s: seen serial number ->%s<-\n",
 				progname, string);
-                    if(strcasecmp(string, serialNumber) != 0){
+                    if(strncasecmp(string, serialNumber, strlen(serialNumber)) != 0){
                         /* serial number does not match, close handle and continue */
                         usb_close(handle);
                         handle = NULL;
-- 
1.7.1

Attachment: pgpfUoB3boHH4.pgp
Description: PGP signature

_______________________________________________
avrdude-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/avrdude-dev

Reply via email to