summaryrefslogtreecommitdiff
path: root/spectro/usbio_lx.c
diff options
context:
space:
mode:
Diffstat (limited to 'spectro/usbio_lx.c')
-rw-r--r--spectro/usbio_lx.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/spectro/usbio_lx.c b/spectro/usbio_lx.c
index 44307fd..7cc37e6 100644
--- a/spectro/usbio_lx.c
+++ b/spectro/usbio_lx.c
@@ -460,8 +460,11 @@ char **pnames /* List of process names to try and kill before opening */
if ((rv = p->usbd->fd = open(p->usbd->dpath, O_RDWR)) < 0) {
a1logd(p->log, 8, "usb_open_port: open '%s' config %d failed (%d) (Permissions ?)\n",p->usbd->dpath,config,rv);
if (retries <= 0) {
- if (kpc != NULL)
+ if (kpc != NULL) {
+ if (kpc->th->result < 0)
+ a1logw(p->log, "usb_open_port: killing competing processes failed\n");
kpc->del(kpc);
+ }
a1loge(p->log, ICOM_SYS, "usb_open_port: open '%s' config %d failed (%d) (Permissions ?)\n",p->usbd->dpath,config,rv);
return ICOM_SYS;
}
@@ -636,25 +639,53 @@ static void *urb_reaper(void *context) {
pa[0].events = POLLIN | POLLOUT;
pa[0].revents = 0;
+ /* Setup to wait for a shutdown signal via the sd_pipe */
pa[1].fd = p->usbd->sd_pipe[0];
pa[1].events = POLLIN;
pa[1].revents = 0;
- /* Wait for fd to become ready or shutdown */
- if ((rv = poll_x(pa, 2, -1)) < 0 || pa[1].revents || pa[0].revents == 0) {
- a1logd(p->log, 6, "urb_reaper: poll returned %d and events %d %d\n",rv,pa[0].revents,pa[1].revents);
+ /* Wait for fd to become ready or fail */
+ rv = poll_x(pa, 2, -1);
+
+ /* Failed */
+ if (rv < 0) {
+ a1logd(p->log, 2, "urb_reaper: poll failed with %d\n",rv);
+ if (errc++ < 5) {
+ continue;
+ }
+ a1logd(p->log, 2, "urb_reaper: poll failed too many times - shutting down\n");
p->usbd->shutdown = 1;
break;
}
+ /* Shutdown event */
+ if (pa[1].revents != 0) {
+ a1logd(p->log, 6, "urb_reaper: poll returned events %d %d - shutting down\n",
+ pa[0].revents,pa[1].revents);
+ p->usbd->shutdown = 1;
+ break;
+ }
+
+ /* Hmm. poll returned without event from fd. */
+ if (pa[0].revents == 0) {
+ a1logd(p->log, 6, "urb_reaper: poll returned events %d %d - ignoring\n",
+ pa[0].revents,pa[1].revents);
+ continue;
+ }
+
/* Not sure what this returns if there is nothing there */
rv = ioctl(p->usbd->fd, USBDEVFS_REAPURBNDELAY, &out);
+ if (rv == EAGAIN) {
+ a1logd(p->log, 2, "urb_reaper: reap returned EAGAIN - ignored\n");
+ continue;
+ }
if (rv < 0) {
a1logd(p->log, 2, "urb_reaper: reap failed with %d\n",rv);
if (errc++ < 5) {
continue;
}
+ a1logd(p->log, 2, "urb_reaper: reap failed too many times - shutting down\n");
p->usbd->shutdown = 1;
break;
}
@@ -662,7 +693,7 @@ static void *urb_reaper(void *context) {
errc = 0;
if (out == NULL) {
- a1logd(p->log, 2, "urb_reaper: reap returned NULL URB\n");
+ a1logd(p->log, 2, "urb_reaper: reap returned NULL URB - ignored\n");
continue;
}
@@ -710,7 +741,7 @@ static void *urb_reaper(void *context) {
pthread_mutex_lock(&req->lock);
for (i = req->nourbs-1; i >= 0; i--) {
- req->urbs[i].urb.status = ICOM_SYS;
+ req->urbs[i].urb.status = -ENOMSG; /* Use ENOMSG as error marker */
}
req->nourbs = 0;
pthread_cond_signal(&req->cond);
@@ -803,7 +834,7 @@ static int icoms_usb_transaction(
bp += req.urbs[i].urb.buffer_length;
req.urbs[i].urb.status = -EINPROGRESS;
}
-a1logd(p->log, 8, "icoms_usb_transaction: reset req 0x%p nourbs to %d\n",&req,req.nourbs);
+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);
@@ -815,7 +846,7 @@ a1logd(p->log, 8, "icoms_usb_transaction: reset req 0x%p nourbs to %d\n",&req,re
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.urbs[i].urb.status = -ENOMSG; /* Mark it as failed to submit */
req.nourbs--;
}
}
@@ -824,7 +855,7 @@ a1logd(p->log, 8, "icoms_usb_transaction: reset req 0x%p nourbs to %d\n",&req,re
amutex_lock(cancelt->cmtx);
cancelt->hcancel = (void *)&req;
cancelt->state = 1;
- amutex_unlock(cancelt->cond); /* Signal any thread waiting for IO start */
+ amutex_unlock(cancelt->condx); /* Signal any thread waiting for IO start */
amutex_unlock(cancelt->cmtx);
}
@@ -887,7 +918,7 @@ a1logd(p->log, 8, "icoms_usb_transaction: reset req 0x%p nourbs to %d\n",&req,re
int stat = req.urbs[i].urb.status;
xlength += req.urbs[i].urb.actual_length;
- if (stat == ICOM_SYS) { /* Submit or cancel failed */
+ if (stat == -ENOMSG) { /* 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)
@@ -919,7 +950,7 @@ done:;
amutex_lock(cancelt->cmtx);
cancelt->hcancel = (void *)NULL;
if (cancelt->state == 0)
- amutex_unlock(cancelt->cond);
+ amutex_unlock(cancelt->condx);
cancelt->state = 2;
amutex_unlock(cancelt->cmtx);
}