diff --git a/docs/man/ups.conf.txt b/docs/man/ups.conf.txt
index 4877852..0bc84f5 100644
--- a/docs/man/ups.conf.txt
+++ b/docs/man/ups.conf.txt
@@ -154,6 +154,16 @@ system from getting stuck due to a broken driver or UPS.
 +
 The default is 45 seconds.
 
+*usb_set_altinterface*[='altinterface']::
+
+Optional.  Force the USB code to call `usb_set_altinterface(0)`, as was done in
+NUT 2.7.2 and earlier.  This should not be necessary, since the default for
+`bAlternateSetting` (as shown in lsusb) is zero on all USB devices seen to
+date.  However, this redundant call to `usb_set_altinterface()` prevents
+certain UPSes from working on Mac OS X. If your UPS requires explicitly setting
+the alternate interface, include this flag, and email the nut-upsdev list with
+details about your UPS and operating system.
+
 *default.<variable>*::
 
 Optional.  Set a default value for <variable> which is used in case the UPS
diff --git a/drivers/blazer_usb.c b/drivers/blazer_usb.c
index 7ba4df2..14d2af9 100644
--- a/drivers/blazer_usb.c
+++ b/drivers/blazer_usb.c
@@ -498,14 +498,7 @@ void upsdrv_help(void)
 void upsdrv_makevartable(void)
 {
 	addvar(VAR_VALUE, "subdriver", "Serial-over-USB subdriver selection");
-	addvar(VAR_VALUE, "vendorid", "Regular expression to match UPS Manufacturer numerical ID (4 digits hexadecimal)");
-	addvar(VAR_VALUE, "productid", "Regular expression to match UPS Product numerical ID (4 digits hexadecimal)");
-
-	addvar(VAR_VALUE, "vendor", "Regular expression to match UPS Manufacturer string");
-	addvar(VAR_VALUE, "product", "Regular expression to match UPS Product string");
-	addvar(VAR_VALUE, "serial", "Regular expression to match UPS Serial number");
-
-	addvar(VAR_VALUE, "bus", "Regular expression to match USB bus name");
+	nut_usb_addvars();
 
 	addvar(VAR_VALUE, "langid_fix", "Apply the language ID workaround to the krauler subdriver (0x409 or 0x4095)");
 
diff --git a/drivers/libusb.c b/drivers/libusb.c
index fd8f5b9..8625ed6 100644
--- a/drivers/libusb.c
+++ b/drivers/libusb.c
@@ -49,6 +49,23 @@ upsdrv_info_t comm_upsdrv_info = {
 
 static void libusb_close(usb_dev_handle *udev);
 
+/*! Add USB-related driver variables with addvar().
+ * This removes some code duplication across the USB drivers.
+ */
+void nut_usb_addvars(void)
+{
+	/* allow -x vendor=X, vendorid=X, product=X, productid=X, serial=X */
+	addvar(VAR_VALUE, "vendor", "Regular expression to match UPS Manufacturer string");
+	addvar(VAR_VALUE, "product", "Regular expression to match UPS Product string");
+	addvar(VAR_VALUE, "serial", "Regular expression to match UPS Serial number");
+
+	addvar(VAR_VALUE, "vendorid", "Regular expression to match UPS Manufacturer numerical ID (4 digits hexadecimal)");
+	addvar(VAR_VALUE, "productid", "Regular expression to match UPS Product numerical ID (4 digits hexadecimal)");
+
+	addvar(VAR_VALUE, "bus", "Regular expression to match USB bus name");
+	addvar(VAR_VALUE, "usb_set_altinterface", "Force redundant call to usb_set_altinterface() (value=bAlternateSetting; default=0)");
+}
+
 /* From usbutils: workaround libusb API goofs:  "byte" should never be sign extended;
  * using "char" is trouble.  Likewise, sizes should never be negative.
  */
@@ -70,6 +87,45 @@ static inline int matches(USBDeviceMatcher_t *matcher, USBDevice_t *device) {
 	return matcher->match_function(device, matcher->privdata);
 }
 
+/*! If needed, set the USB alternate interface.
+ *
+ * In NUT 2.7.2 and earlier, the following call was made unconditionally:
+ *   usb_set_altinterface(udev, 0);
+ *
+ * Although harmless on Linux and *BSD, this extra call prevents old Tripp Lite
+ * devices from working on Mac OS X (presumably the OS is already setting
+ * altinterface to 0).
+ */
+static int nut_usb_set_altinterface(usb_dev_handle *udev)
+{
+	int altinterface = 0, ret = 0;
+	char *alt_string, *endp = NULL;
+
+	if(testvar("usb_set_altinterface")) {
+		alt_string = getval("usb_set_altinterface");
+		if(alt_string) {
+			altinterface = (int)strtol(alt_string, &endp, 10);
+			if(endp && !(endp[0] == 0)) {
+				upslogx(LOG_WARNING, "%s: '%s' is not a valid number", __func__, alt_string);
+			}
+			if(altinterface < 0 || altinterface > 255) {
+				upslogx(LOG_WARNING, "%s: setting bAlternateInterface to %d will probably not work", __func__, altinterface);
+			}
+		}
+		/* set default interface */
+		upsdebugx(2, "%s: calling usb_set_altinterface(udev, %d)", __func__, altinterface);
+		ret = usb_set_altinterface(udev, altinterface);
+		if(ret != 0) {
+			upslogx(LOG_WARNING, "%s: usb_set_altinterface(udev, %d) returned %d (%s)",
+					__func__, altinterface, ret, usb_strerror() );
+		}
+		upslogx(LOG_NOTICE, "%s: usb_set_altinterface() should not be necessary - please email the nut-upsdev list with information about your UPS.", __func__);
+	} else {
+		upsdebugx(3, "%s: skipped usb_set_altinterface(udev, 0)", __func__);
+	}
+	return ret;
+}
+
 #define usb_control_msg         typesafe_control_msg
 
 /* On success, fill in the curDevice structure and return the report
@@ -220,8 +276,7 @@ static int libusb_open(usb_dev_handle **udevp, USBDevice_t *curDevice, USBDevice
 			}
 #endif
 
-			/* set default interface */
-			usb_set_altinterface(udev, 0);
+			nut_usb_set_altinterface(udev);
 
 			if (!callback) {
 				return 1;
diff --git a/drivers/nutdrv_qx.c b/drivers/nutdrv_qx.c
index f27e89b..a3ff8ac 100644
--- a/drivers/nutdrv_qx.c
+++ b/drivers/nutdrv_qx.c
@@ -1264,14 +1264,8 @@ void	upsdrv_makevartable(void)
 
 #ifdef QX_USB
 	addvar(VAR_VALUE, "subdriver", "Serial-over-USB subdriver selection");
-	addvar(VAR_VALUE, "vendorid", "Regular expression to match UPS Manufacturer numerical ID (4 digits hexadecimal)");
-	addvar(VAR_VALUE, "productid", "Regular expression to match UPS Product numerical ID (4 digits hexadecimal)");
-
-	addvar(VAR_VALUE, "vendor", "Regular expression to match UPS Manufacturer string");
-	addvar(VAR_VALUE, "product", "Regular expression to match UPS Product string");
-	addvar(VAR_VALUE, "serial", "Regular expression to match UPS Serial number");
-
-	addvar(VAR_VALUE, "bus", "Regular expression to match USB bus name");
+	/* allow -x vendor=X, vendorid=X, product=X, productid=X, serial=X */
+	nut_usb_addvars();
 
 	addvar(VAR_VALUE, "langid_fix", "Apply the language ID workaround to the krauler subdriver (0x409 or 0x4095)");
 #endif	/* QX_USB */
diff --git a/drivers/tripplite_usb.c b/drivers/tripplite_usb.c
index 0122e52..771d10c 100644
--- a/drivers/tripplite_usb.c
+++ b/drivers/tripplite_usb.c
@@ -1401,12 +1401,8 @@ void upsdrv_makevartable(void)
 		DEFAULT_OFFDELAY);
 	addvar(VAR_VALUE, "offdelay", msg);
 
-        /* allow -x vendor=X, vendorid=X, product=X, productid=X, serial=X */
-	addvar(VAR_VALUE, "vendor", "Regular expression to match UPS Manufacturer string");
-	addvar(VAR_VALUE, "product", "Regular expression to match UPS Product string");
-	addvar(VAR_VALUE, "serial", "Regular expression to match UPS Serial number");
-	addvar(VAR_VALUE, "productid", "Regular expression to match UPS Product numerical ID (4 digits hexadecimal)");
-	addvar(VAR_VALUE, "bus", "Regular expression to match USB bus name");
+	/* allow -x vendor=X, vendorid=X, product=X, productid=X, serial=X */
+	nut_usb_addvars();
 
 	snprintf(msg, sizeof msg, "Minimum battery voltage, corresponding to 10%% charge (default=%.1f)",
 		MIN_VOLT);
diff --git a/drivers/usb-common.h b/drivers/usb-common.h
index ad08172..d7a3ff4 100644
--- a/drivers/usb-common.h
+++ b/drivers/usb-common.h
@@ -93,4 +93,6 @@ typedef struct {
 int is_usb_device_supported(usb_device_id_t *usb_device_id_list, 
 							USBDevice_t *device);
 
+void nut_usb_addvars(void);
+
 #endif /* NUT_USB_COMMON_H */
diff --git a/drivers/usbhid-ups.c b/drivers/usbhid-ups.c
index cdfbad7..117e4bc 100644
--- a/drivers/usbhid-ups.c
+++ b/drivers/usbhid-ups.c
@@ -737,12 +737,8 @@ void upsdrv_makevartable(void)
 
 #ifndef SHUT_MODE
 	/* allow -x vendor=X, vendorid=X, product=X, productid=X, serial=X */
-	addvar(VAR_VALUE, "vendor", "Regular expression to match UPS Manufacturer string");
-	addvar(VAR_VALUE, "product", "Regular expression to match UPS Product string");
-	addvar(VAR_VALUE, "serial", "Regular expression to match UPS Serial number");
-	addvar(VAR_VALUE, "vendorid", "Regular expression to match UPS Manufacturer numerical ID (4 digits hexadecimal)");
-	addvar(VAR_VALUE, "productid", "Regular expression to match UPS Product numerical ID (4 digits hexadecimal)");
-	addvar(VAR_VALUE, "bus", "Regular expression to match USB bus name");
+	nut_usb_addvars();
+
 	addvar(VAR_FLAG, "explore", "Diagnostic matching of unsupported UPS");
 	addvar(VAR_FLAG, "maxreport", "Activate tweak for buggy APC Back-UPS firmware");
 #else
diff --git a/tools/nut-usbinfo.pl b/tools/nut-usbinfo.pl
index 989cef2..b5c70ee 100755
--- a/tools/nut-usbinfo.pl
+++ b/tools/nut-usbinfo.pl
@@ -209,7 +209,7 @@ sub gen_usb_files
 sub find_usbdevs
 {
 	# maybe there's an option to turn off all .* files, but anyway this is stupid
-	return $File::Find::prune = 1 if ($_ eq '.svn') || ($_ =~ /^\.#/);
+	return $File::Find::prune = 1 if ($_ eq '.svn') || ($_ =~ /^\.#/) || ($_ =~ /\.orig$/);
 
 	my $nameFile=$_;
 	my $lastComment="";
@@ -265,8 +265,8 @@ sub find_usbdevs
 				}
 			}
 
-			# store date (to be optimized)
-			# and don't overwritte actual vendor names with empty values
+			# store data (to be optimized)
+			# and don't overwrite actual vendor names with empty values
 			if( (!$vendorName{$VendorID}) or (($vendorName{$VendorID} eq "") and ($VendorName ne "")) )
 			{
 				$vendorName{$VendorID}=trim($VendorName);
