|
|
|
|
@@ -51,6 +51,8 @@
|
|
|
|
|
|
|
|
|
|
#include <alloca.h>
|
|
|
|
|
|
|
|
|
|
#include "sys.h" /* for debug */
|
|
|
|
|
|
|
|
|
|
static pthread_t tid_main;
|
|
|
|
|
static pthread_t tid_usbip;
|
|
|
|
|
|
|
|
|
|
@@ -304,6 +306,7 @@ hc_handle_control_urb (struct urb *urb)
|
|
|
|
|
uint16_t remain = urb->len;
|
|
|
|
|
uint64_t l;
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hcu 0");
|
|
|
|
|
|
|
|
|
|
usbc_ep0.urb = urb;
|
|
|
|
|
@@ -311,10 +314,14 @@ hc_handle_control_urb (struct urb *urb)
|
|
|
|
|
if (r < 0)
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hcu 1");
|
|
|
|
|
|
|
|
|
|
if (urb->dir == USBIP_DIR_OUT)
|
|
|
|
|
{ /* Output from host to device. */
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("hcu: %d\n", r);
|
|
|
|
|
|
|
|
|
|
while (r == 0)
|
|
|
|
|
{
|
|
|
|
|
if (remain > 64)
|
|
|
|
|
@@ -340,7 +347,9 @@ hc_handle_control_urb (struct urb *urb)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{ /* Input from device to host. */
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hcu 2");
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (remain > 64)
|
|
|
|
|
@@ -353,28 +362,38 @@ hc_handle_control_urb (struct urb *urb)
|
|
|
|
|
if (r < 0)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hcu 3");
|
|
|
|
|
|
|
|
|
|
remain -= r;
|
|
|
|
|
urb->data_p += r;
|
|
|
|
|
if (r < 64)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hcu 4");
|
|
|
|
|
|
|
|
|
|
if (r >= 0)
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hcu 5");
|
|
|
|
|
|
|
|
|
|
read (usbc_ep0.eventfd, &l, sizeof (l));
|
|
|
|
|
r = control_read_status_transaction ();
|
|
|
|
|
if (r >= 0)
|
|
|
|
|
r = remain;
|
|
|
|
|
}
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hcu 6");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r < 0)
|
|
|
|
|
{
|
|
|
|
|
error:
|
|
|
|
|
fprintf (stderr, "hcu 7 %d\n", r);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("hcu 7 %d\n", r);
|
|
|
|
|
|
|
|
|
|
/* recovery. */
|
|
|
|
|
usbc_ep0.state = USB_STATE_READY;
|
|
|
|
|
}
|
|
|
|
|
@@ -393,7 +412,9 @@ hc_handle_control_urb (struct urb *urb)
|
|
|
|
|
else
|
|
|
|
|
urb->len = 0;
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("hu-next: %d (%d)\n", urb->len, urb->seq);
|
|
|
|
|
|
|
|
|
|
usbc_ep0.urb = NULL;
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
@@ -452,7 +473,8 @@ usbip_finish_urb (struct urb *urb, int r)
|
|
|
|
|
memset (&msg_rep, 0, sizeof (msg_rep));
|
|
|
|
|
msg_rep.len = htonl (urb->len);
|
|
|
|
|
|
|
|
|
|
fprintf (stderr, "ufu: %d (%d)\n", r, urb->seq);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("ufu: %d (%d)\n", r, urb->seq);
|
|
|
|
|
|
|
|
|
|
if (r < 0)
|
|
|
|
|
msg_rep.status = htonl (r);
|
|
|
|
|
@@ -489,7 +511,9 @@ hc_handle_data_urb (struct usb_control *usbc_p)
|
|
|
|
|
uint16_t count;
|
|
|
|
|
struct urb *urb = usbc_p->urb;
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hc_hdu 0");
|
|
|
|
|
|
|
|
|
|
if (urb->remain > 64)
|
|
|
|
|
count = 64;
|
|
|
|
|
else
|
|
|
|
|
@@ -497,7 +521,9 @@ hc_handle_data_urb (struct usb_control *usbc_p)
|
|
|
|
|
|
|
|
|
|
if (urb->dir == USBIP_DIR_OUT)
|
|
|
|
|
{ /* Output from host to device. */
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hc_hdu 1");
|
|
|
|
|
|
|
|
|
|
r = write_data_transaction (usbc_p, urb->ep, urb->data_p, count);
|
|
|
|
|
if (r < 0)
|
|
|
|
|
return r;
|
|
|
|
|
@@ -509,14 +535,17 @@ hc_handle_data_urb (struct usb_control *usbc_p)
|
|
|
|
|
{
|
|
|
|
|
size_t len = urb->len - urb->remain;
|
|
|
|
|
|
|
|
|
|
fprintf (stderr, "->data: %lu\n", len);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("->data: %lu\n", len);
|
|
|
|
|
|
|
|
|
|
// successfully finished
|
|
|
|
|
if (len)
|
|
|
|
|
{
|
|
|
|
|
char *s = alloca (len + 1);
|
|
|
|
|
memcpy (s, urb->data, len);
|
|
|
|
|
s[len] = 0;
|
|
|
|
|
fprintf (stderr, " : %s\n", s);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf (" : %s\n", s);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -525,7 +554,9 @@ hc_handle_data_urb (struct usb_control *usbc_p)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{ /* Input from device to host. */
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("hc_hdu 2");
|
|
|
|
|
|
|
|
|
|
r = read_data_transaction (usbc_p, urb->ep, urb->data_p, count);
|
|
|
|
|
if (r < 0)
|
|
|
|
|
return r;
|
|
|
|
|
@@ -536,14 +567,17 @@ hc_handle_data_urb (struct usb_control *usbc_p)
|
|
|
|
|
{
|
|
|
|
|
size_t len = urb->len - urb->remain;
|
|
|
|
|
|
|
|
|
|
fprintf (stderr, "<-data: %lu %d\n", len, r);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("<-data: %lu %d\n", len, r);
|
|
|
|
|
|
|
|
|
|
// successfully finished
|
|
|
|
|
if (len)
|
|
|
|
|
{
|
|
|
|
|
char *s = alloca (len + 1);
|
|
|
|
|
memcpy (s, urb->data, len);
|
|
|
|
|
s[len] = 0;
|
|
|
|
|
fprintf (stderr, " : %s\n", s);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf (" : %s\n", s);
|
|
|
|
|
}
|
|
|
|
|
urb->len = len;
|
|
|
|
|
return 0;
|
|
|
|
|
@@ -652,6 +686,7 @@ usbip_handle_urb (uint32_t seq)
|
|
|
|
|
urb->remain = urb->len = ntohl (msg_cmd.len);
|
|
|
|
|
urb->data_p = urb->data;
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("URB: dir=%s, ep=%d, len=%d\n", urb->dir==USBIP_DIR_IN? "IN": "OUT",
|
|
|
|
|
urb->ep, urb->len);
|
|
|
|
|
|
|
|
|
|
@@ -663,6 +698,7 @@ usbip_handle_urb (uint32_t seq)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (urb->ep == 0)
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("URB: %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
|
|
|
|
urb->setup[0], urb->setup[1], urb->setup[2], urb->setup[3],
|
|
|
|
|
urb->setup[4], urb->setup[5], urb->setup[6], urb->setup[7]);
|
|
|
|
|
@@ -777,7 +813,9 @@ usbip_process_cmd (void)
|
|
|
|
|
const char *device_list;
|
|
|
|
|
size_t device_list_size;
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("Device List\n");
|
|
|
|
|
|
|
|
|
|
if (attached)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, "REQ list while attached\n");
|
|
|
|
|
@@ -808,7 +846,9 @@ usbip_process_cmd (void)
|
|
|
|
|
size_t attach_size;
|
|
|
|
|
char busid[32];
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("Attach device\n");
|
|
|
|
|
|
|
|
|
|
if (attached)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, "REQ attach while attached\n");
|
|
|
|
|
@@ -828,6 +868,7 @@ usbip_process_cmd (void)
|
|
|
|
|
if (attach
|
|
|
|
|
&& (size_t)send (fd, attach, attach_size, 0) == attach_size)
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("Attach device!\n");
|
|
|
|
|
attached = 1;
|
|
|
|
|
pthread_mutex_unlock (&fd_mutex);
|
|
|
|
|
@@ -847,6 +888,7 @@ usbip_process_cmd (void)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("URB SUBMIT! %d\n", msg.seq);
|
|
|
|
|
usbip_handle_urb (msg.seq);
|
|
|
|
|
}
|
|
|
|
|
@@ -908,6 +950,7 @@ usbip_process_cmd (void)
|
|
|
|
|
if (found)
|
|
|
|
|
msg_rep.status = htonl(-ECONNRESET);
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("URB UNLINK! %d: %s\n", seq, found?"o":"x");
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock (&fd_mutex);
|
|
|
|
|
@@ -940,7 +983,9 @@ usbip_ep_ready (struct usb_control *usbc_p)
|
|
|
|
|
|
|
|
|
|
if (!usbc_p->urb)
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("???usbip_ep_ready");
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1088,7 +1133,8 @@ usbip_run_server (void *arg)
|
|
|
|
|
if ((pollfds[0].revents & POLLNVAL)
|
|
|
|
|
|| (pollfds[0].revents & POLLERR))
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, "Error on USBIP client socket: %d\n", pollfds[0].revents);
|
|
|
|
|
fprintf (stderr, "Error on USBIP client socket: %d\n",
|
|
|
|
|
pollfds[0].revents);
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
if ((pollfds[0].revents & POLLIN))
|
|
|
|
|
@@ -1110,7 +1156,9 @@ usbip_run_server (void *arg)
|
|
|
|
|
}
|
|
|
|
|
if ((pollfds[i*2].revents & POLLIN))
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("poll in read");
|
|
|
|
|
|
|
|
|
|
usbip_ep_ready (&usbc_ep_in[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1122,7 +1170,9 @@ usbip_run_server (void *arg)
|
|
|
|
|
}
|
|
|
|
|
if ((pollfds[i*2+1].revents & POLLIN))
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("poll out read");
|
|
|
|
|
|
|
|
|
|
usbip_ep_ready (&usbc_ep_out[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -1163,7 +1213,8 @@ control_setup_transaction (struct urb *urb)
|
|
|
|
|
r = -EAGAIN;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, "cst error %d\n", usbc_ep0.state);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("cst error %d\n", usbc_ep0.state);
|
|
|
|
|
r = -EPIPE;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock (&usbc_ep0.mutex);
|
|
|
|
|
@@ -1187,7 +1238,8 @@ control_write_data_transaction (char *buf, uint16_t count)
|
|
|
|
|
{
|
|
|
|
|
if (usbc_ep0.len < count)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, "*** usbc_ep0.len < count");
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("*** usbc_ep0.len < count");
|
|
|
|
|
r = -EPIPE;
|
|
|
|
|
usbc_ep0.state = USB_STATE_STALL;
|
|
|
|
|
}
|
|
|
|
|
@@ -1224,9 +1276,12 @@ control_write_status_transaction (void)
|
|
|
|
|
pthread_mutex_lock (&usbc_ep0.mutex);
|
|
|
|
|
if (usbc_ep0.state == USB_STATE_READY)
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("control_write_status_transaction");
|
|
|
|
|
|
|
|
|
|
if (usbc_ep0.len != 0)
|
|
|
|
|
fprintf (stderr, "*** ACK length %d\n", usbc_ep0.len);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("*** ACK length %d\n", usbc_ep0.len);
|
|
|
|
|
usbc_ep0.state = USB_STATE_NAK;
|
|
|
|
|
notify_device (USB_INTR_DATA_TRANSFER, 0, USBIP_DIR_IN);
|
|
|
|
|
r = 0;
|
|
|
|
|
@@ -1255,7 +1310,10 @@ control_read_data_transaction (char *buf, uint16_t count)
|
|
|
|
|
if (usbc_ep0.state == USB_STATE_READY)
|
|
|
|
|
{
|
|
|
|
|
if (usbc_ep0.len > count)
|
|
|
|
|
fprintf (stderr, "***c read: length %d > %d\n", usbc_ep0.len, count);
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("***c read: length %d > %d\n", usbc_ep0.len, count);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
count = usbc_ep0.len;
|
|
|
|
|
|
|
|
|
|
@@ -1337,7 +1395,10 @@ read_data_transaction (struct usb_control *usbc_p,
|
|
|
|
|
int ep_num, char *buf, uint16_t count)
|
|
|
|
|
{
|
|
|
|
|
if (usbc_p->len > count)
|
|
|
|
|
fprintf (stderr, "*** length %d > %d\n", usbc_p->len, count);
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("*** length %d > %d\n", usbc_p->len, count);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
count = usbc_p->len;
|
|
|
|
|
|
|
|
|
|
@@ -1902,7 +1963,9 @@ static int handle_in0 (struct usb_dev *dev)
|
|
|
|
|
== (STANDARD_REQUEST | DEVICE_RECIPIENT)))
|
|
|
|
|
{
|
|
|
|
|
/* XXX: record the assigned address of this device??? */
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("Set Address: %d\n", dev->dev_req.value);
|
|
|
|
|
|
|
|
|
|
r = USB_EVENT_DEVICE_ADDRESSED;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@@ -1917,7 +1980,9 @@ static int handle_in0 (struct usb_dev *dev)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("handle_in0 error");
|
|
|
|
|
|
|
|
|
|
dev->state = STALLED;
|
|
|
|
|
pthread_mutex_lock (&usbc_ep0.mutex);
|
|
|
|
|
usbc_ep0.state = USB_STATE_STALL;
|
|
|
|
|
@@ -1955,7 +2020,9 @@ static void handle_out0 (struct usb_dev *dev)
|
|
|
|
|
* Or else, unexpected state.
|
|
|
|
|
* STALL the endpoint, until we receive the next SETUP token.
|
|
|
|
|
*/
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("handle_out0 error");
|
|
|
|
|
|
|
|
|
|
dev->state = STALLED;
|
|
|
|
|
pthread_mutex_lock (&usbc_ep0.mutex);
|
|
|
|
|
usbc_ep0.state = USB_STATE_STALL;
|
|
|
|
|
@@ -2077,7 +2144,9 @@ usb_lld_current_configuration (struct usb_dev *dev)
|
|
|
|
|
void
|
|
|
|
|
usb_lld_ctrl_error (struct usb_dev *dev)
|
|
|
|
|
{
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
puts ("ctrl_error");
|
|
|
|
|
|
|
|
|
|
dev->state = STALLED;
|
|
|
|
|
pthread_mutex_lock (&usbc_ep0.mutex);
|
|
|
|
|
usbc_ep0.state = USB_STATE_STALL;
|
|
|
|
|
@@ -2134,6 +2203,8 @@ usb_lld_stall_tx (int ep_num)
|
|
|
|
|
usbc_p->state = USB_STATE_STALL;
|
|
|
|
|
notify_hostcontroller (usbc_p);
|
|
|
|
|
pthread_mutex_unlock (&usbc_p->mutex);
|
|
|
|
|
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("stall tx %d\n", ep_num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2146,6 +2217,7 @@ usb_lld_stall_rx (int ep_num)
|
|
|
|
|
usbc_p->state = USB_STATE_STALL;
|
|
|
|
|
notify_hostcontroller (usbc_p);
|
|
|
|
|
pthread_mutex_unlock (&usbc_p->mutex);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("stall rx %d\n", ep_num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2161,6 +2233,7 @@ usb_lld_rx_enable_buf (int ep_num, void *buf, size_t len)
|
|
|
|
|
|
|
|
|
|
notify_hostcontroller (usbc_p);
|
|
|
|
|
pthread_mutex_unlock (&usbc_p->mutex);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("usb_lld_rx_enable_buf: %d\n", ep_num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2176,5 +2249,6 @@ usb_lld_tx_enable_buf (int ep_num, const void *buf, size_t len)
|
|
|
|
|
usbc_p->len = len;
|
|
|
|
|
notify_hostcontroller (usbc_p);
|
|
|
|
|
pthread_mutex_unlock (&usbc_p->mutex);
|
|
|
|
|
if ((debug & DEBUG_USB))
|
|
|
|
|
printf ("usb_lld_tx_enable_buf: %d %ld\n", ep_num, len);
|
|
|
|
|
}
|
|
|
|
|
|