diff --git a/cgminer.c b/cgminer.c index 177f61c4..befe57e7 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6360,6 +6360,21 @@ bool add_cgpu(struct cgpu_info*cgpu) return true; } +struct device_drv *copy_drv(struct device_drv *drv) +{ + struct device_drv *copy; + char buf[100]; + + if (unlikely(!(copy = malloc(sizeof(*copy))))) { + sprintf(buf, "Failed to allocate device_drv copy of %s (%s)", + drv->name, drv->copy ? "copy" : "original"); + quit(1, buf); + } + memcpy(copy, drv, sizeof(*copy)); + copy->copy = true; + return copy; +} + int main(int argc, char *argv[]) { bool pools_active = false; diff --git a/driver-bitforce.c b/driver-bitforce.c index f1196322..0181b170 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -240,6 +240,9 @@ shin: if (bitforce->name != blank) free(bitforce->name); + if (bitforce->drv->copy) + free(bitforce->drv); + free(bitforce); return false; diff --git a/driver-modminer.c b/driver-modminer.c index 0868e85e..246947b4 100644 --- a/driver-modminer.c +++ b/driver-modminer.c @@ -182,7 +182,7 @@ static bool modminer_detect_one(struct libusb_device *dev, struct usb_find_devic for (i = 0; i < buf[0]; i++) { struct cgpu_info *tmp = calloc(1, sizeof(*tmp)); - tmp->drv = modminer->drv; + tmp->drv = copy_drv(modminer->drv); tmp->name = devname; sprintf(devpath, "%d:%d:%d", @@ -202,6 +202,8 @@ static bool modminer_detect_one(struct libusb_device *dev, struct usb_find_devic if (!add_cgpu(tmp)) { free(tmp->device_path); + if (tmp->drv->copy) + free(tmp->drv); free(tmp); goto unshin; } @@ -211,6 +213,9 @@ static bool modminer_detect_one(struct libusb_device *dev, struct usb_find_devic added = true; } + if (modminer->drv->copy) + free(modminer->drv); + free(modminer); return true; @@ -223,6 +228,9 @@ shin: if (!added) free(modminer->modminer_mutex); + if (modminer->drv->copy) + free(modminer->drv); + free(modminer); if (added) diff --git a/miner.h b/miner.h index 4e888f32..b89d072e 100644 --- a/miner.h +++ b/miner.h @@ -299,8 +299,13 @@ struct device_drv { void (*hw_error)(struct thr_info *); void (*thread_shutdown)(struct thr_info *); void (*thread_enable)(struct thr_info *); + + // Does it need to be free()d? + bool copy; }; +extern struct device_drv *copy_drv(struct device_drv*); + enum dev_enable { DEV_ENABLED, DEV_DISABLED, diff --git a/usbutils.c b/usbutils.c index bebd722d..ebfcc0b2 100644 --- a/usbutils.c +++ b/usbutils.c @@ -891,6 +891,14 @@ bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find libusb_free_config_descriptor(config); + // Allow a name change based on the idVendor+idProduct + // N.B. must be done before calling add_cgpu() + if (strcmp(cgpu->drv->name, found->name)) { + if (!cgpu->drv->copy) + cgpu->drv = copy_drv(cgpu->drv); + cgpu->drv->name = (char *)(found->name); + } + return true; cldame: @@ -919,14 +927,14 @@ static bool usb_check_device(struct device_drv *drv, struct libusb_device *dev, } if (desc.idVendor != look->idVendor || desc.idProduct != look->idProduct) { - applog(LOG_DEBUG, "%s looking for %04x:%04x but found %04x:%04x instead", - drv->name, look->idVendor, look->idProduct, desc.idVendor, desc.idProduct); + applog(LOG_DEBUG, "%s looking for %s %04x:%04x but found %04x:%04x instead", + drv->name, look->name, look->idVendor, look->idProduct, desc.idVendor, desc.idProduct); return false; } - applog(LOG_DEBUG, "%s looking for and found %04x:%04x", - drv->name, look->idVendor, look->idProduct); + applog(LOG_DEBUG, "%s looking for and found %s %04x:%04x", + drv->name, look->name, look->idVendor, look->idProduct); return true; }