unsigned char *descriptors;
int descriptors_len;
int active_config; /* cache val for !sysfs_can_relate_devices */
+ int fd;
};
struct linux_device_handle_priv {
/* we hit this error path frequently with buggy devices :( */
usbi_warn(DEVICE_CTX(dev),
"get_configuration failed ret=%d errno=%d", r, errno);
- priv->active_config = -1;
- } else {
- if (active_config > 0) {
- priv->active_config = active_config;
- } else {
- /* some buggy devices have a configuration 0, but we're
- * reaching into the corner of a corner case here, so let's
- * not support buggy devices in these circumstances.
- * stick to the specs: a configuration value of 0 means
- * unconfigured. */
- usbi_warn(DEVICE_CTX(dev),
- "active cfg 0? assuming unconfigured device");
- priv->active_config = -1;
- }
- }
-
- return LIBUSB_SUCCESS;
+ //priv->active_config = -1;
+ return LIBUSB_ERROR_IO;
+ }
+// else {
+// if (active_config > 0) {
+// priv->active_config = active_config;
+// } else {
+// /* some buggy devices have a configuration 0, but we're
+// * reaching into the corner of a corner case here, so let's
+// * not support buggy devices in these circumstances.
+// * stick to the specs: a configuration value of 0 means
+// * unconfigured. */
+// usbi_warn(DEVICE_CTX(dev),
+// "active cfg 0? assuming unconfigured device");
+// priv->active_config = -1;
+// }
+// }
+//
+ return active_config;
+// return LIBUSB_SUCCESS;
}
static int initialize_device(struct libusb_device *dev, uint8_t busnum,
return LIBUSB_SUCCESS;
}
+static int linux_initialize_device(struct libusb_device *dev,
+ uint8_t busnum, uint8_t devaddr, int fd) {
+
+ usbi_dbg("linux_initialize_device");
+
+ struct linux_device_priv *priv = _device_priv(dev);
+ struct libusb_context *ctx = DEVICE_CTX(dev);
+ uint8_t desc[4096]; // max descriptor size is 4096 bytes
+ int speed;
+ ssize_t r;
+
+ dev->bus_number = busnum;
+ dev->device_address = devaddr;
+
+ usbi_dbg("cache descriptors in memory");
+
+ priv->descriptors_len = 0;
+ priv->fd = 0;
+ memset(desc, 0, sizeof(desc));
+ if (!lseek(fd, 0, SEEK_SET)) {
+ // ディスクリプタを読み込んでローカルキャッシュする
+ int length = read(fd, desc, sizeof(desc));
+ usbi_dbg("Device::init read returned %d errno %d\n", length, errno);
+ if (length > 0) {
+ priv->fd = fd;
+ priv->descriptors = usbi_reallocf(priv->descriptors, length);
+ if (!priv->descriptors) {
+ return (int)LIBUSB_ERROR_NO_MEM;
+ //RETURN(LIBUSB_ERROR_NO_MEM, int);
+ }
+ priv->descriptors_len = length;
+ memcpy(priv->descriptors, desc, length);
+ }
+ }
+
+ if (priv->descriptors_len < DEVICE_DESC_LENGTH) {
+ usbi_err(ctx, "short descriptor read (%d)", priv->descriptors_len);
+ //LOGE("short descriptor read (%d)", priv->descriptors_len);
+ return (int)LIBUSB_ERROR_IO;
+ //RETURN(LIBUSB_ERROR_IO, int);
+ }
+
+ if (fd < 0) { // if could not get fd of usbfs with read/write access
+ /* cannot send a control message to determine the active
+ * config. just assume the first one is active. */
+ usbi_warn(ctx, "Missing rw usbfs access; cannot determine "
+ "active configuration descriptor");
+ if (priv->descriptors_len
+ >= (DEVICE_DESC_LENGTH + LIBUSB_DT_CONFIG_SIZE)) {
+ struct libusb_config_descriptor config;
+ usbi_parse_descriptor(priv->descriptors + DEVICE_DESC_LENGTH,
+ "bbwbbbbb", &config, 0);
+ priv->active_config = config.bConfigurationValue;
+ } else
+ priv->active_config = -1; /* No config dt */
+
+ return (int)LIBUSB_SUCCESS;
+ //RETURN(LIBUSB_SUCCESS, int);
+ }
+ // if we could get fd of usbfs with read/write access
+ r = usbfs_get_active_config(dev, fd);
+ if (r > 0) {
+ priv->active_config = r;
+ r = LIBUSB_SUCCESS;
+ } else if (r == 0) {
+ /* some buggy devices have a configuration 0, but we're
+ * reaching into the corner of a corner case here, so let's
+ * not support buggy devices in these circumstances.
+ * stick to the specs: a configuration value of 0 means
+ * unconfigured. */
+ usbi_dbg("active cfg 0? assuming unconfigured device");
+ priv->active_config = -1;
+ r = LIBUSB_SUCCESS;
+ } else if (r == LIBUSB_ERROR_IO) {
+ /* buggy devices sometimes fail to report their active config.
+ * assume unconfigured and continue the probing */
+ usbi_warn(ctx, "couldn't query active configuration, assuming"
+ " unconfigured");
+ priv->active_config = -1;
+ r = LIBUSB_SUCCESS;
+ } /* else r < 0, just return the error code */
+
+ return (int)r;
+ //RETURN(r, int);
+}
+
+
+
+int linux_generate_device(struct libusb_context *ctx, struct libusb_device **dev,
+ int vid, int pid, const char *serial, int fd, int busnum, int devaddr) {
+
+ usbi_dbg("linux_generate_device, fd:%d, serial:%s", fd, serial);
+ unsigned long session_id;
+ int r = 0;
+
+ *dev = NULL;
+ /* FIXME: session ID is not guaranteed unique as addresses can wrap and
+ * will be reused. instead we should add a simple sysfs attribute with
+ * a session ID. */
+ session_id = busnum << 8 | devaddr;
+ usbi_dbg("allocating new device for %d/%d (session %ld)", busnum, devaddr, session_id);
+ *dev = usbi_alloc_device(ctx, session_id); // この時点で参照カウンタ=1
+ if (!dev) {
+ usbi_dbg("ret %d", LIBUSB_ERROR_NO_MEM);
+ return (int)LIBUSB_ERROR_NO_MEM;
+ }
+
+ r = linux_initialize_device(*dev, busnum, devaddr, fd);
+ if (r < 0) {
+ usbi_err("initialize_device failed: ret=%d", r);
+ goto out;
+ }
+ r = usbi_sanitize_device(*dev);
+ if (r < 0) {
+ usbi_err("usbi_sanitize_device failed: ret=%d", r);
+ goto out;
+ }
+
+out:
+ if (r < 0) {
+ libusb_unref_device(*dev); // ここで参照カウンタが0になって破棄される
+ *dev = NULL;
+ } else {
+ usbi_connect_device(*dev);
+ }
+
+ usbi_dbg("linux_generate_device ret=%d", r);
+ return (int)r;
+}
+
+
int linux_enumerate_device(struct libusb_context *ctx,
uint8_t busnum, uint8_t devaddr, const char *sysfs_dir)
{