Fix USB emulation driver for GNU/Linux.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka
2021-10-04 10:05:45 +09:00
parent d36e9274b1
commit 86ccc02be7
2 changed files with 45 additions and 23 deletions

View File

@@ -1,3 +1,7 @@
2021-10-04 NIIBE Yutaka <gniibe@fsij.org>
* mcu/usb-usbip.c (URB_DATA_SIZE): Tweak the value.
2021-02-26 NIIBE Yutaka <gniibe@fsij.org> 2021-02-26 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 2.2 * VERSION: 2.2

View File

@@ -22,10 +22,26 @@
*/ */
/* /*
FIXME: * This driver is intended to emulate USB full-speed device, which
RESET handling * maximum packet size is 64.
USB Shutdown *
Use reply structure of its own * "USBIP" is actually URB over network (instead of USB packet over
* network), and its (current) naive protocol may expose possible
* demarcation problem, which never occurs in real host-device; In
* real host-device relationship, it is host side, which does
* composition/decomposition of URB to/from packets. In an
* implmentation of USB device with USBIP, it needs to be device side,
* which does composition/decomposition of URB to/from packets.
*
* In this implementation of USB driver, URB_DATA_SIZE is defined as
* (65544+10), because (major) target device intended is CCID. In the
* CCID specification, you can find the value 65544+10.
*
*
* FIXME:
* RESET handling
* USB Shutdown
* Use reply structure of its own
*/ */
#include <pthread.h> #include <pthread.h>
@@ -96,7 +112,7 @@ struct urb {
struct urb *next; struct urb *next;
struct urb *prev; struct urb *prev;
uint16_t remain; uint32_t remain;
char *data_p; char *data_p;
pthread_t tid; pthread_t tid;
@@ -236,7 +252,7 @@ attach_device (char busid[32], size_t *len_p)
return (const char *)&usbip_usb_device; return (const char *)&usbip_usb_device;
} }
#define URB_DATA_SIZE 65535 #define URB_DATA_SIZE (65544+10)
struct usbip_msg_cmd { struct usbip_msg_cmd {
uint32_t devid; uint32_t devid;
@@ -299,12 +315,14 @@ static int write_data_transaction (struct usb_control *usbc_p,
static int read_data_transaction (struct usb_control *usbc_p, static int read_data_transaction (struct usb_control *usbc_p,
int ep_num, char *buf, uint16_t count); int ep_num, char *buf, uint16_t count);
#define USB_MAX_PACKET_SIZE 64 /* For USB fullspeed device. */
static int static int
hc_handle_control_urb (struct urb *urb) hc_handle_control_urb (struct urb *urb)
{ {
int r; int r;
uint16_t count; uint16_t count;
uint16_t remain = urb->len; uint32_t remain = urb->len;
uint64_t l; uint64_t l;
if ((debug & DEBUG_USB)) if ((debug & DEBUG_USB))
@@ -325,10 +343,10 @@ hc_handle_control_urb (struct urb *urb)
while (r == 0) while (r == 0)
{ {
if (remain > 64) if (remain > USB_MAX_PACKET_SIZE)
count = 64; count = USB_MAX_PACKET_SIZE;
else else
count = remain; count = (uint16_t)remain;
read (usbc_ep0.eventfd, &l, sizeof (l)); read (usbc_ep0.eventfd, &l, sizeof (l));
r = control_write_data_transaction (urb->data_p, count); r = control_write_data_transaction (urb->data_p, count);
@@ -337,7 +355,7 @@ hc_handle_control_urb (struct urb *urb)
urb->data_p += count; urb->data_p += count;
remain -= count; remain -= count;
if (count < 64) if (count < USB_MAX_PACKET_SIZE)
break; break;
} }
if (r >= 0) if (r >= 0)
@@ -353,10 +371,10 @@ hc_handle_control_urb (struct urb *urb)
while (1) while (1)
{ {
if (remain > 64) if (remain > USB_MAX_PACKET_SIZE)
count = 64; count = USB_MAX_PACKET_SIZE;
else else
count = remain; count = (uint16_t)remain;
read (usbc_ep0.eventfd, &l, sizeof (l)); read (usbc_ep0.eventfd, &l, sizeof (l));
r = control_read_data_transaction (urb->data_p, count); r = control_read_data_transaction (urb->data_p, count);
@@ -368,7 +386,7 @@ hc_handle_control_urb (struct urb *urb)
remain -= r; remain -= r;
urb->data_p += r; urb->data_p += r;
if (r < 64) if (r < USB_MAX_PACKET_SIZE)
break; break;
} }
@@ -516,10 +534,10 @@ hc_handle_data_urb (struct usb_control *usbc_p)
if ((debug & DEBUG_USB)) if ((debug & DEBUG_USB))
puts ("hc_hdu 0"); puts ("hc_hdu 0");
if (urb->remain > 64) if (urb->remain > USB_MAX_PACKET_SIZE)
count = 64; count = USB_MAX_PACKET_SIZE;
else else
count = urb->remain; count = (uint16_t)urb->remain;
if (urb->dir == USBIP_DIR_OUT) if (urb->dir == USBIP_DIR_OUT)
{ /* Output from host to device. */ { /* Output from host to device. */
@@ -533,7 +551,7 @@ hc_handle_data_urb (struct usb_control *usbc_p)
urb->data_p += count; urb->data_p += count;
urb->remain -= count; urb->remain -= count;
if (urb->remain == 0 || count < 64) if (urb->remain == 0 || count < USB_MAX_PACKET_SIZE)
{ {
size_t len = urb->len - urb->remain; size_t len = urb->len - urb->remain;
@@ -565,7 +583,7 @@ hc_handle_data_urb (struct usb_control *usbc_p)
urb->remain -= r; urb->remain -= r;
urb->data_p += r; urb->data_p += r;
if (urb->remain == 0 || r < 64) if (urb->remain == 0 || r < USB_MAX_PACKET_SIZE)
{ {
size_t len = urb->len - urb->remain; size_t len = urb->len - urb->remain;
@@ -596,7 +614,7 @@ issue_get_desc (void)
{ {
struct urb *urb; struct urb *urb;
urb = malloc (sizeof (struct urb) + 64); urb = malloc (sizeof (struct urb) + USB_MAX_PACKET_SIZE);
urb->next = urb->prev = urb; urb->next = urb->prev = urb;
@@ -606,14 +624,14 @@ issue_get_desc (void)
urb->setup[3] = 1; /* Value H: desc_type */ urb->setup[3] = 1; /* Value H: desc_type */
urb->setup[4] = 0; /* Index */ urb->setup[4] = 0; /* Index */
urb->setup[5] = 0; urb->setup[5] = 0;
urb->setup[6] = 64; /* Length */ urb->setup[6] = USB_MAX_PACKET_SIZE; /* Length */
urb->setup[7] = 0; urb->setup[7] = 0;
urb->data_p = urb->data; urb->data_p = urb->data;
urb->seq = 0; urb->seq = 0;
urb->devid = 0; urb->devid = 0;
urb->dir = USBIP_DIR_IN; urb->dir = USBIP_DIR_IN;
urb->ep = 0; urb->ep = 0;
urb->remain = urb->len = 64; urb->remain = urb->len = USB_MAX_PACKET_SIZE;
hc_handle_control_urb (urb); hc_handle_control_urb (urb);
return urb; return urb;
} }