571 lines
17 KiB
C
571 lines
17 KiB
C
$NetBSD$
|
|
|
|
Attempt to make actually function with NetBSD ugen(4).
|
|
|
|
--- spectro/usbio_bsd.c.orig 2018-07-09 02:57:13.000000000 +0000
|
|
+++ spectro/usbio_bsd.c
|
|
@@ -67,13 +67,15 @@ icompaths *p
|
|
#if defined(__FreeBSD__)
|
|
"/dev/usb/[0-9]*.*.0", /* FreeBSD >= 8 */
|
|
"/dev/ugen[0-9]*", /* FreeBSD < 8, but no .E */
|
|
+#elif defined(__NetBSD__)
|
|
+ "/dev/ugen[0-9]*.00", /* NetBSD */
|
|
#else
|
|
- "/dev/ugen/[0-9]*.00", /* NetBSD, OpenBSD */
|
|
+ "/dev/ugen/[0-9]*.00", /* OpenBSD */
|
|
#endif
|
|
NULL
|
|
};
|
|
int vid, pid;
|
|
- int nconfig = 0, nep = 0;
|
|
+ unsigned int configix, nconfig, nep;
|
|
char *dpath;
|
|
devType itype;
|
|
struct usb_idevice *usbd = NULL;
|
|
@@ -85,6 +87,9 @@ icompaths *p
|
|
glob_t g;
|
|
int fd;
|
|
struct usb_device_info di;
|
|
+ usb_device_descriptor_t udd;
|
|
+ struct usb_interface_desc uid;
|
|
+ struct usb_config_desc ucd;
|
|
int rv, found = 0;
|
|
|
|
if (paths[j] == NULL)
|
|
@@ -121,12 +126,8 @@ icompaths *p
|
|
continue;
|
|
}
|
|
|
|
- // ~~99 need to check number of end points ~~~
|
|
- // ~~99 and number of configs
|
|
- nconfig = 1;
|
|
-
|
|
-//USB_GET_DEVICEINFO struct usb_device_info
|
|
-//USB_GET_DEVICE_DESC struct usb_device_descriptor
|
|
+ if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) < 0)
|
|
+ continue;
|
|
|
|
/* Allocate an idevice so that we can fill in the end point information */
|
|
if ((usbd = (struct usb_idevice *) calloc(sizeof(struct usb_idevice), 1)) == NULL) {
|
|
@@ -136,8 +137,56 @@ icompaths *p
|
|
return ICOM_SYS;
|
|
}
|
|
|
|
- usbd->nconfig = nconfig;
|
|
+ usbd->nconfig = nconfig = udd.bNumConfigurations;
|
|
|
|
+ /* Read the configuration descriptors looking for the first configuration, first interface, */
|
|
+ /* and extract the number of end points for each configuration */
|
|
+ for (configix = 0; configix < nconfig; configix++) {
|
|
+ ucd.ucd_config_index = configix;
|
|
+ if (ioctl(fd, USB_GET_CONFIG_DESC, &ucd) < 0) {
|
|
+ free(usbd);
|
|
+ close(fd);
|
|
+ break;
|
|
+ }
|
|
+ usbd->nifce = ucd.ucd_desc.bNumInterface;
|
|
+ usbd->config = ucd.ucd_desc.bConfigurationValue;
|
|
+
|
|
+ if (ucd.ucd_desc.bConfigurationValue != 1)
|
|
+ continue;
|
|
+
|
|
+ uid.uid_config_index = USB_CURRENT_CONFIG_INDEX;
|
|
+ uid.uid_interface_index = 0;
|
|
+ uid.uid_alt_index = USB_CURRENT_ALT_INDEX;
|
|
+
|
|
+ if (ioctl(fd, USB_GET_INTERFACE_DESC, &uid) < 0) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ nep = uid.uid_desc.bNumEndpoints;
|
|
+
|
|
+ unsigned int epix;
|
|
+ struct usb_endpoint_desc ued;
|
|
+ for (epix = 0; epix < nep; epix++) {
|
|
+ ued.ued_config_index = USB_CURRENT_CONFIG_INDEX;
|
|
+ ued.ued_interface_index = 0;
|
|
+ ued.ued_alt_index = USB_CURRENT_ALT_INDEX;
|
|
+ ued.ued_endpoint_index = epix;
|
|
+ if (ioctl(fd, USB_GET_ENDPOINT_DESC, &ued) < 0) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ const unsigned int ad = ued.ued_desc.bEndpointAddress;
|
|
+ usbd->EPINFO(ad).valid = 1;
|
|
+ usbd->EPINFO(ad).addr = ad;
|
|
+ usbd->EPINFO(ad).packetsize = UGETW(ued.ued_desc.wMaxPacketSize);
|
|
+ usbd->EPINFO(ad).type = ued.ued_desc.bmAttributes & IUSB_ENDPOINT_TYPE_MASK;
|
|
+ usbd->EPINFO(ad).interface = uid.uid_desc.bInterfaceNumber;
|
|
+ usbd->EPINFO(ad).fd = -1;
|
|
+
|
|
+ a1logd(p->log, 6, "set ep ad 0x%x packetsize %d type %d\n",ad,usbd->EPINFO(ad).packetsize,usbd->EPINFO(ad).type);
|
|
+ }
|
|
+ }
|
|
+
|
|
/* Found a known instrument ? */
|
|
if ((itype = inst_usb_match(vid, pid, nep)) != instUnknown) {
|
|
char pname[400], *cp;
|
|
@@ -245,52 +294,18 @@ void usb_close_port(icoms *p) {
|
|
|
|
a1logd(p->log, 6, "usb_close_port: called\n");
|
|
|
|
-#ifdef NEVER // ~~99
|
|
if (p->is_open && p->usbd != NULL) {
|
|
- struct usbdevfs_urb urb;
|
|
- unsigned char buf[8+IUSB_DESC_TYPE_DEVICE_SIZE];
|
|
- int iface, rv;
|
|
-
|
|
- /* Release all the interfaces */
|
|
- for (iface = 0; iface < p->nifce; iface++)
|
|
- ioctl(p->usbd->fd, USBDEVFS_RELEASEINTERFACE, &iface);
|
|
-
|
|
- /* Workaround for some bugs - reset device on close */
|
|
- if (p->uflags & icomuf_reset_before_close) {
|
|
- if ((rv = ioctl(p->usbd->fd, USBDEVFS_RESET, NULL)) != 0) {
|
|
- a1logd(p->log, 1, "usb_close_port: reset returned %d\n",rv);
|
|
- }
|
|
- }
|
|
-
|
|
- if (p->usbd->running) { /* If reaper is still running */
|
|
- unsigned char buf[1] = { 0 };
|
|
-
|
|
- a1logd(p->log, 6, "usb_close_port: waking reaper thread to trigger exit\n");
|
|
- p->usbd->shutdown = 1;
|
|
-
|
|
- if (write(p->usbd->sd_pipe[1], buf, 1) < 1) {
|
|
- a1logd(p->log, 1, "usb_close_port: writing to sd_pipe failed with '%s'\n", strerror(errno));
|
|
- /* Hmm. We could be in trouble ? */
|
|
- }
|
|
+ for (int i = 15; i >= 0; i--) {
|
|
+ close(p->ep[i].fd);
|
|
}
|
|
- a1logd(p->log, 6, "usb_close_port: waiting for reaper thread\n");
|
|
- pthread_join(p->usbd->thread, NULL); /* Wait for urb reaper thread to exit */
|
|
- close(p->usbd->fd);
|
|
- pthread_mutex_destroy(&p->usbd->lock);
|
|
- close(p->usbd->sd_pipe[0]);
|
|
- close(p->usbd->sd_pipe[1]);
|
|
-
|
|
a1logd(p->log, 6, "usb_close_port: usb port has been released and closed\n");
|
|
}
|
|
p->is_open = 0;
|
|
-#endif // ~~99
|
|
|
|
/* Find it and delete it from our static cleanup list */
|
|
usb_delete_from_cleanup_list(p);
|
|
}
|
|
|
|
-static void *urb_reaper(void *context); /* Declare */
|
|
-
|
|
/* Open a USB port for all our uses. */
|
|
/* This always re-opens the port */
|
|
/* return icom error */
|
|
@@ -309,7 +324,6 @@ char **pnames /* List of process names
|
|
if (p->is_open)
|
|
p->close_port(p);
|
|
|
|
-#ifdef NEVER // ~~99
|
|
/* Make sure the port is open */
|
|
if (!p->is_open) {
|
|
int rv, i, iface;
|
|
@@ -344,12 +358,16 @@ char **pnames /* List of process names
|
|
p->cconfig = 1;
|
|
|
|
if (p->cconfig != config) {
|
|
+#if 0
|
|
if ((rv = ioctl(p->usbd->fd, USBDEVFS_SETCONFIGURATION, &config)) != 0) {
|
|
a1logd(p->log, 1, "icoms_usb_setconfig failed with %d\n",rv);
|
|
return ICOM_SYS;
|
|
}
|
|
p->cconfig = config;
|
|
a1logd(p->log, 6, "usb_open_port: set config %d OK\n",config);
|
|
+#else
|
|
+ a1logd(p->log, 6, "usb_open_port: set config %d unimplemented\n",config);
|
|
+#endif
|
|
}
|
|
|
|
/* We're done */
|
|
@@ -362,6 +380,7 @@ char **pnames /* List of process names
|
|
/* Claim all the interfaces */
|
|
for (iface = 0; iface < p->nifce; iface++) {
|
|
|
|
+#if 0
|
|
if ((rv = ioctl(p->usbd->fd, USBDEVFS_CLAIMINTERFACE, &iface)) < 0) {
|
|
struct usbdevfs_getdriver getd;
|
|
getd.interface = iface;
|
|
@@ -386,6 +405,30 @@ char **pnames /* List of process names
|
|
return ICOM_SYS;
|
|
}
|
|
}
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ char epdpath[33];
|
|
+ snprintf(epdpath, sizeof(epdpath), "%s.%02d", p->usbd->dpath, 0);
|
|
+ int fd;
|
|
+ fd = open(epdpath, O_RDWR);
|
|
+ p->ep[0].fd = fd;
|
|
+
|
|
+ for (int i = 1; i < 16; i++) {
|
|
+ int flg;
|
|
+ if (p->ep[i].valid && p->ep[i+16].valid)
|
|
+ flg = O_RDWR;
|
|
+ else if (p->ep[i].valid)
|
|
+ flg = O_WRONLY;
|
|
+ else if (p->ep[i+16].valid)
|
|
+ flg = O_RDONLY;
|
|
+ else
|
|
+ continue;
|
|
+
|
|
+ snprintf(epdpath, sizeof(epdpath), "%s.%02d", p->usbd->dpath, i);
|
|
+ int fd = open(epdpath, flg);
|
|
+
|
|
+ p->ep[i].fd = p->ep[i+16].fd = fd;
|
|
}
|
|
|
|
/* Clear any errors. */
|
|
@@ -407,25 +450,10 @@ char **pnames /* List of process names
|
|
p->rd_qa = 8;
|
|
a1logd(p->log, 8, "usb_open_port: 'serial' read quanta = packet size = %d\n",p->rd_qa);
|
|
|
|
- /* Start the reaper thread to handle URB completions */
|
|
- if ((rv = pipe(p->usbd->sd_pipe)) < 0) {
|
|
- a1loge(p->log, ICOM_SYS, "usb_open_port: creat pipe failed with %d\n",rv);
|
|
- return ICOM_SYS;
|
|
- }
|
|
- pthread_mutex_init(&p->usbd->lock, NULL);
|
|
-
|
|
- p->usbd->running = 1;
|
|
- if ((rv = pthread_create(&p->usbd->thread, NULL, urb_reaper, (void*)p)) < 0) {
|
|
- p->usbd->running = 0;
|
|
- a1loge(p->log, ICOM_SYS, "usb_open_port: creating urb reaper thread failed with %s\n",rv);
|
|
- return ICOM_SYS;
|
|
- }
|
|
-
|
|
p->is_open = 1;
|
|
a1logd(p->log, 8, "usb_open_port: USB port is now open\n");
|
|
}
|
|
|
|
-#endif // ~~99
|
|
/* Install the cleanup signal handlers, and add to our cleanup list */
|
|
usb_install_signal_handlers(p);
|
|
|
|
@@ -444,88 +472,23 @@ static int icoms_usb_transaction(
|
|
int length,
|
|
unsigned int timeout /* In msec */
|
|
) {
|
|
- int type;
|
|
int remlen;
|
|
unsigned char *bp;
|
|
- int xlength = 0;
|
|
+ ssize_t xlength = 0;
|
|
int i;
|
|
int reqrv = ICOM_OK;
|
|
|
|
-#ifdef NEVER // ~~99
|
|
in_usb_rw++;
|
|
a1logd(p->log, 8, "icoms_usb_transaction: req type 0x%x ep 0x%x size %d\n",ttype,endpoint,length);
|
|
|
|
- if (!p->usbd->running) {
|
|
- in_usb_rw--;
|
|
- a1logv(p->log, 1, "icoms_usb_transaction: reaper thread is not running\n");
|
|
- return ICOM_SYS;
|
|
- }
|
|
+ /* XXX USB_SET_TIMEOUT */
|
|
|
|
- /* Translate icoms transfer type of Linux */
|
|
- switch (ttype) {
|
|
- case icom_usb_trantype_command:
|
|
- type = USBDEVFS_URB_TYPE_CONTROL;
|
|
- break;
|
|
- case icom_usb_trantype_interrutpt:
|
|
- type = USBDEVFS_URB_TYPE_INTERRUPT;
|
|
- break;
|
|
- case icom_usb_trantype_bulk:
|
|
- type = USBDEVFS_URB_TYPE_BULK;
|
|
- break;
|
|
- }
|
|
-
|
|
- /* Setup the icom req and urbs */
|
|
- req.urbs = NULL;
|
|
- pthread_mutex_init(&req.lock, NULL);
|
|
- pthread_cond_init(&req.cond, NULL);
|
|
-
|
|
- /* Linux historically only copes with 16384 length urbs, */
|
|
- /* so break up longer requests into multiple urbs */
|
|
-
|
|
- req.cancelled = 0;
|
|
- req.nourbs = req.nurbs = (length + (1 << 14)-1) >> 14;
|
|
- if ((req.urbs = (usbio_urb *)calloc(sizeof(usbio_urb), req.nourbs)) == NULL) {
|
|
- in_usb_rw--;
|
|
- a1loge(p->log, ICOM_SYS, "icoms_usb_transaction: control transfer too big! (%d)\n",length);
|
|
- return ICOM_SYS;
|
|
- }
|
|
+ if ((endpoint & IUSB_ENDPOINT_DIR_MASK) == IUSB_ENDPOINT_OUT)
|
|
+ xlength = write(p->ep[endpoint&0xf].fd, buffer, length);
|
|
+ else
|
|
+ xlength = read(p->ep[endpoint&0xf].fd, buffer, length);
|
|
|
|
- bp = buffer;
|
|
- remlen = length;
|
|
- for (i = 0; i < req.nurbs; i++) {
|
|
- req.urbs[i].req = &req;
|
|
- req.urbs[i].urbno = i;
|
|
- /* Setup Linux URB */
|
|
- req.urbs[i].urb.usercontext = &req.urbs[i];
|
|
- req.urbs[i].urb.type = type;
|
|
- if (type != USBDEVFS_URB_TYPE_CONTROL)
|
|
- req.urbs[i].urb.endpoint = endpoint;
|
|
- if (remlen > 16384)
|
|
- req.urbs[i].urb.buffer_length = 16384;
|
|
- else
|
|
- req.urbs[i].urb.buffer_length = remlen;
|
|
- req.urbs[i].urb.buffer = (void *)bp;
|
|
- remlen -= req.urbs[i].urb.buffer_length;
|
|
- bp += req.urbs[i].urb.buffer_length;
|
|
- req.urbs[i].urb.status = -EINPROGRESS;
|
|
- }
|
|
-a1logd(p->log, 8, "icoms_usb_transaction: reset req %p nourbs to %d\n",&req,req.nourbs);
|
|
-
|
|
- /* Add our request to the req list so that it can be cancelled on reap failure */
|
|
- pthread_mutex_lock(&p->usbd->lock);
|
|
- req.next = p->usbd->reqs;
|
|
- p->usbd->reqs = &req;
|
|
- pthread_mutex_unlock(&p->usbd->lock);
|
|
-
|
|
- /* submit the URBs */
|
|
- for (i = 0; i < req.nurbs; i++) {
|
|
- if ((rv = ioctl(p->usbd->fd, USBDEVFS_SUBMITURB, &req.urbs[i].urb)) < 0) {
|
|
- a1logd(p->log, 1, "coms_usb_transaction: Submitting urb to fd %d failed with %d\n",p->usbd->fd, rv);
|
|
- req.urbs[i].urb.status = ICOM_SYS; /* Mark it as failed to submit */
|
|
- req.nourbs--;
|
|
- }
|
|
- }
|
|
-
|
|
+#if 0
|
|
if (cancelt != NULL) {
|
|
amutex_lock(cancelt->cmtx);
|
|
cancelt->hcancel = (void *)&req;
|
|
@@ -533,85 +496,7 @@ a1logd(p->log, 8, "icoms_usb_transaction
|
|
amutex_unlock(cancelt->cond); /* Signal any thread waiting for IO start */
|
|
amutex_unlock(cancelt->cmtx);
|
|
}
|
|
-
|
|
- /* Wait for the reaper to wake us, or for a timeout, */
|
|
- /* or for the reaper to die. */
|
|
- pthread_mutex_lock(&req.lock);
|
|
- if (req.nourbs > 0) {
|
|
- struct timeval tv;
|
|
- struct timespec ts;
|
|
-
|
|
- // this is unduly complicated...
|
|
- gettimeofday(&tv, NULL);
|
|
- ts.tv_sec = tv.tv_sec + timeout/1000;
|
|
- ts.tv_nsec = (tv.tv_usec + (timeout % 1000) * 1000) * 1000L;
|
|
- if (ts.tv_nsec > 1000000000L) {
|
|
- ts.tv_nsec -= 1000000000L;
|
|
- ts.tv_sec++;
|
|
- }
|
|
-
|
|
- for(;;) { /* Ignore spurious wakeups */
|
|
- if ((rv = pthread_cond_timedwait(&req.cond, &req.lock, &ts)) != 0) {
|
|
- if (rv != ETIMEDOUT) {
|
|
- pthread_mutex_unlock(&req.lock);
|
|
- a1logd(p->log, 1, "coms_usb_transaction: pthread_cond_timedwait failed with %d\n",rv);
|
|
- rv = ICOM_SYS;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- /* Timed out - cancel the remaining URB's */
|
|
- a1logd(p->log, 8, "coms_usb_transaction: time out - cancel remaining URB's\n");
|
|
- reqrv = ICOM_TO;
|
|
- if (!req.cancelled && (rv = cancel_req(p, &req, -1)) != ICOM_OK) {
|
|
- pthread_mutex_unlock(&req.lock);
|
|
- reqrv = ICOM_SYS;
|
|
- /* Since cancelling failed, we can't wait for them to be reaped */
|
|
- goto done;
|
|
- }
|
|
-
|
|
- /* Wait for the cancelled URB's to be reaped */
|
|
- for (;req.nourbs > 0;) { /* Ignore spurious wakeups */
|
|
- if ((rv = pthread_cond_wait(&req.cond, &req.lock)) != 0) {
|
|
- pthread_mutex_unlock(&req.lock);
|
|
- a1logd(p->log, 1, "coms_usb_transaction: pthread_cond_wait failed with %d\n",rv);
|
|
- reqrv = ICOM_SYS;
|
|
- /* Waiting for reap failed, so give up */
|
|
- goto done;
|
|
- }
|
|
- }
|
|
- } else {
|
|
- a1logd(p->log, 8, "coms_usb_transaction: reap - %d left\n",req.nourbs);
|
|
- }
|
|
- if (req.nourbs <= 0)
|
|
- break; /* All urbs's are done */
|
|
- }
|
|
- }
|
|
- pthread_mutex_unlock(&req.lock);
|
|
-
|
|
- /* Compute the overall result by going through the urbs. */
|
|
- for (i = 0; i < req.nurbs; i++) {
|
|
- int stat = req.urbs[i].urb.status;
|
|
- xlength += req.urbs[i].urb.actual_length;
|
|
-
|
|
- if (stat == ICOM_SYS) { /* Submit or cancel failed */
|
|
- reqrv = ICOM_SYS;
|
|
- } else if (reqrv == ICOM_OK && stat < 0 && stat != -ECONNRESET) { /* Error result */
|
|
- if ((endpoint & IUSB_ENDPOINT_DIR_MASK) == IUSB_ENDPOINT_OUT)
|
|
- reqrv = ICOM_USBW;
|
|
- else
|
|
- reqrv = ICOM_USBR;
|
|
- } else if (reqrv == ICOM_OK && stat == -ECONNRESET) { /* Cancelled */
|
|
- reqrv = ICOM_CANC;
|
|
- } else if (reqrv == ICOM_OK
|
|
- && req.urbs[i].urb.actual_length < req.urbs[i].urb.buffer_length) {
|
|
- /* Disregard any following urb's status - they are probably cancelled */
|
|
- break;
|
|
- }
|
|
- /* reqrv == ICOM_TO will ignore urb status */
|
|
- }
|
|
-
|
|
- if (ttype == icom_usb_trantype_command)
|
|
- xlength += IUSB_REQ_HEADER_SIZE; /* Account for header - linux doesn't */
|
|
+#endif
|
|
|
|
/* requested size wasn't transferred ? */
|
|
if (reqrv == ICOM_OK && xlength != length)
|
|
@@ -620,6 +505,7 @@ a1logd(p->log, 8, "icoms_usb_transaction
|
|
if (transferred != NULL)
|
|
*transferred = xlength;
|
|
|
|
+#if 0
|
|
done:;
|
|
if (cancelt != NULL) {
|
|
amutex_lock(cancelt->cmtx);
|
|
@@ -629,20 +515,7 @@ done:;
|
|
cancelt->state = 2;
|
|
amutex_unlock(cancelt->cmtx);
|
|
}
|
|
-
|
|
- /* Remove our request from the list */
|
|
- pthread_mutex_lock(&p->usbd->lock);
|
|
- preq = &p->usbd->reqs;
|
|
- while (*preq != &req && *preq != NULL) /* Find it */
|
|
- preq = &((*preq)->next);
|
|
- if (*preq != NULL)
|
|
- *preq = (*preq)->next;
|
|
- pthread_mutex_unlock(&p->usbd->lock);
|
|
-
|
|
- if (req.urbs != NULL)
|
|
- free(req.urbs);
|
|
- pthread_cond_destroy(&req.cond);
|
|
- pthread_mutex_destroy(&req.lock);
|
|
+#endif
|
|
|
|
if (in_usb_rw < 0)
|
|
exit(0);
|
|
@@ -650,7 +523,6 @@ done:;
|
|
in_usb_rw--;
|
|
|
|
a1logd(p->log, 8, "coms_usb_transaction: returning err 0x%x and %d bytes\n",reqrv, xlength);
|
|
-#endif // ~~99
|
|
|
|
return reqrv;
|
|
}
|
|
@@ -665,51 +537,34 @@ int value, int index, unsigned char *byt
|
|
int timeout) {
|
|
int reqrv = ICOM_OK;
|
|
int dirw = (requesttype & IUSB_REQ_DIR_MASK) == IUSB_REQ_HOST_TO_DEV ? 1 : 0;
|
|
- unsigned char *buf;
|
|
+ struct usb_ctl_request ucr;
|
|
|
|
a1logd(p->log, 8, "icoms_usb_control_msg: type 0x%x req 0x%x size %d\n",requesttype,request,size);
|
|
|
|
-#ifdef NEVER // ~~99
|
|
- /* Allocate a buffer for the ctrl header + payload */
|
|
- if ((buf = calloc(1, IUSB_REQ_HEADER_SIZE + size)) == NULL) {
|
|
- a1loge(p->log, ICOM_SYS, "icoms_usb_control_msg: calloc failed\n");
|
|
- return ICOM_SYS;
|
|
- }
|
|
-
|
|
+ ucr.ucr_addr = 0;
|
|
/* Setup the control header */
|
|
- buf[0] = requesttype;
|
|
- buf[1] = request;
|
|
- short2buf(buf + 2, value);
|
|
- short2buf(buf + 4, index);
|
|
- short2buf(buf + 6, size);
|
|
-
|
|
- /* If it's a write, copy the write data into the buffer */
|
|
- if (dirw)
|
|
- memcpy(buf + IUSB_REQ_HEADER_SIZE, bytes, size);
|
|
-
|
|
- reqrv = icoms_usb_transaction(p, NULL, transferred, icom_usb_trantype_command,
|
|
- dirw ? 0x80 : 0x00, buf, IUSB_REQ_HEADER_SIZE + size, timeout);
|
|
-
|
|
- /* If read, copy the data back */
|
|
- if (!dirw)
|
|
- memcpy(bytes, buf + IUSB_REQ_HEADER_SIZE, size);
|
|
+ ucr.ucr_request.bmRequestType = requesttype;
|
|
+ ucr.ucr_request.bRequest = request;
|
|
+ USETW(ucr.ucr_request.wValue, value);
|
|
+ USETW(ucr.ucr_request.wIndex, index);
|
|
+ USETW(ucr.ucr_request.wLength, size);
|
|
+ ucr.ucr_data = bytes;
|
|
+ ucr.ucr_flags = USBD_SHORT_XFER_OK;
|
|
+ ucr.ucr_actlen = 0;
|
|
|
|
- if (transferred != NULL) /* Adjust for header size requested */
|
|
- *transferred -= IUSB_REQ_HEADER_SIZE;
|
|
+ /* XXX USB_SET_TIMEOUT */
|
|
|
|
- free(buf);
|
|
+ if (ioctl(p->ep[0].fd, USB_DO_REQUEST, &ucr) < 0)
|
|
+ return ICOM_SYS; /* XXX */
|
|
+
|
|
+ if (transferred != NULL)
|
|
+ *transferred = ucr.ucr_actlen;
|
|
|
|
-#endif // ~~99
|
|
a1logd(p->log, 8, "icoms_usb_control_msg: returning err 0x%x and %d bytes\n",reqrv, *transferred);
|
|
return reqrv;
|
|
}
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
-/* Time out error return value */
|
|
-
|
|
-#define USBIO_ERROR_TIMEOUT -ETIMEDOUT
|
|
-
|
|
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/* Cancel i/o in another thread */
|
|
int icoms_usb_cancel_io(
|
|
@@ -717,8 +572,9 @@ int icoms_usb_cancel_io(
|
|
usb_cancelt *cancelt
|
|
) {
|
|
int rv = ICOM_OK;
|
|
-#ifdef NEVER // ~~99
|
|
+
|
|
a1logd(p->log, 8, "icoms_usb_cancel_io called\n");
|
|
+#ifdef NEVER // ~~99
|
|
usb_lock_cancel(cancelt);
|
|
if (cancelt->hcancel != NULL)
|
|
rv = cancel_req(p, (usbio_req *)cancelt->hcancel, -1);
|
|
@@ -739,6 +595,8 @@ int icoms_usb_resetep(
|
|
) {
|
|
int rv = ICOM_OK;
|
|
|
|
+ a1logd(p->log, 1, "icoms_usb_resetep unimplemented with %d\n",rv);
|
|
+
|
|
#ifdef NEVER // ~~99
|
|
if ((rv = ioctl(p->usbd->fd, USBDEVFS_RESETEP, &ep)) != 0) {
|
|
a1logd(p->log, 1, "icoms_usb_resetep failed with %d\n",rv);
|
|
@@ -756,6 +614,8 @@ int icoms_usb_clearhalt(
|
|
) {
|
|
int rv = ICOM_OK;
|
|
|
|
+ a1logd(p->log, 1, "icoms_usb_clearhalt unimplemented with %d\n",rv);
|
|
+
|
|
#ifdef NEVER // ~~99
|
|
if ((rv = ioctl(p->usbd->fd, USBDEVFS_CLEAR_HALT, &ep)) != 0) {
|
|
a1logd(p->log, 1, "icoms_usb_clearhalt failed with %d\n",rv);
|