X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=fdf93fecc3bff50ca9341a05219b59152bf5b1c9;hp=573080a92f80ef5ae218312b6f3c9a291add8d03;hb=1a3cb7f83149a08e3d463d7d24d50499b035a149;hpb=1b1bf7e481bc29ffac3b4c6a6da9eeff36beb1d0 diff --git a/src/ftdi.c b/src/ftdi.c index 573080a..fdf93fe 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -406,16 +406,76 @@ void ftdi_list_free2(struct ftdi_device_list *devlist) \retval -9: get serial number failed \retval -11: libusb_get_device_descriptor() failed */ -int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct libusb_device * dev, - char * manufacturer, int mnf_len, char * description, int desc_len, char * serial, int serial_len) +int ftdi_usb_get_strings(struct ftdi_context *ftdi, + struct libusb_device *dev, + char *manufacturer, int mnf_len, + char *description, int desc_len, + char *serial, int serial_len) { - struct libusb_device_descriptor desc; + int ret; if ((ftdi==NULL) || (dev==NULL)) return -1; if (ftdi->usb_dev == NULL && libusb_open(dev, &ftdi->usb_dev) < 0) - ftdi_error_return(-4, "libusb_open() failed"); + ftdi_error_return(-4, "libusb_open() failed"); + + // ftdi->usb_dev will not be NULL when entering ftdi_usb_get_strings2(), so + // it won't be closed either. This allows us to close it whether we actually + // called libusb_open() up above or not. This matches the expected behavior + // (and note) for ftdi_usb_get_strings(). + ret = ftdi_usb_get_strings2(ftdi, dev, + manufacturer, mnf_len, + description, desc_len, + serial, serial_len); + + // only close it if it was successful, as all other return codes close + // before returning already. + if (ret == 0) + ftdi_usb_close_internal(ftdi); + + return ret; +} + +/** + Return device ID strings from the usb device. + + The parameters manufacturer, description and serial may be NULL + or pointer to buffers to store the fetched strings. + + \note The old function ftdi_usb_get_strings() always closes the device. + This version only closes the device if it was opened by it. + + \param ftdi pointer to ftdi_context + \param dev libusb usb_dev to use + \param manufacturer Store manufacturer string here if not NULL + \param mnf_len Buffer size of manufacturer string + \param description Store product description string here if not NULL + \param desc_len Buffer size of product description string + \param serial Store serial string here if not NULL + \param serial_len Buffer size of serial string + + \retval 0: all fine + \retval -1: wrong arguments + \retval -4: unable to open device + \retval -7: get product manufacturer failed + \retval -8: get product description failed + \retval -9: get serial number failed + \retval -11: libusb_get_device_descriptor() failed +*/ +int ftdi_usb_get_strings2(struct ftdi_context *ftdi, struct libusb_device *dev, + char *manufacturer, int mnf_len, + char *description, int desc_len, + char *serial, int serial_len) +{ + struct libusb_device_descriptor desc; + + if ((ftdi==NULL) || (dev==NULL)) + return -1; + + char need_open = (ftdi->usb_dev == NULL); + if (need_open && libusb_open(dev, &ftdi->usb_dev) < 0) + ftdi_error_return(-4, "libusb_open() failed"); if (libusb_get_device_descriptor(dev, &desc) < 0) ftdi_error_return(-11, "libusb_get_device_descriptor() failed"); @@ -447,7 +507,8 @@ int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct libusb_device * dev, } } - ftdi_usb_close_internal (ftdi); + if (need_open) + ftdi_usb_close_internal (ftdi); return 0; } @@ -2585,6 +2646,15 @@ static unsigned char type2bit(unsigned char type, enum ftdi_chip_type chip) default: return 0; } } + case TYPE_R: + { + switch (type) + { + case CHANNEL_IS_UART : return 0; + case CHANNEL_IS_FIFO : return 0x01; + default: return 0; + } + } case TYPE_230X: /* FT230X is only UART */ default: return 0; } @@ -2877,6 +2947,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x14] = eeprom->chip; break; case TYPE_R: + output[0x00] = type2bit(eeprom->channel_a_type, TYPE_R); if (eeprom->high_current == HIGH_CURRENT_DRIVE_R) output[0x00] |= HIGH_CURRENT_DRIVE_R; if (eeprom->external_oscillator) @@ -4124,12 +4195,16 @@ int ftdi_set_eeprom_user_data(struct ftdi_context *ftdi, const char * buf, int s */ int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, unsigned short *eeprom_val) { + unsigned char buf[2]; + if (ftdi == NULL || ftdi->usb_dev == NULL) ftdi_error_return(-2, "USB device unavailable"); - if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, SIO_READ_EEPROM_REQUEST, 0, eeprom_addr, (unsigned char *)eeprom_val, 2, ftdi->usb_read_timeout) != 2) + if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, SIO_READ_EEPROM_REQUEST, 0, eeprom_addr, buf, 2, ftdi->usb_read_timeout) != 2) ftdi_error_return(-1, "reading eeprom failed"); + *eeprom_val = (0xff & buf[0]) | (buf[1] << 8); + return 0; }