From 87767f1be5d8d4adac8d23a285250299eccee3fb Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe@fsij.org>
Date: Fri, 7 Jul 2017 15:46:37 +0900
Subject: Fix error handling of USB-USBIP driver.

---
 ChangeLog       |  6 ++++++
 mcu/usb-usbip.c | 67 ++++++++++++++++++++++++++++++---------------------------
 2 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d6bf520..c14b305 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2017-07-07  NIIBE Yutaka  <gniibe@fsij.org>
+
+	* mcu/usb-usbip.c (usbip_handle_data_urb): Fix error return value.
+	(notify_hostcontroller): New.
+	(usb_lld_stall_tx, usb_lld_stall_rx): Notify host controller side.
+
 2017-07-06  NIIBE Yutaka  <gniibe@fsij.org>
 
 	* mcu/usb-usbip.c (hc_handle_data_urb): Fix the condition of the
diff --git a/mcu/usb-usbip.c b/mcu/usb-usbip.c
index 47882ec..7e093b9 100644
--- a/mcu/usb-usbip.c
+++ b/mcu/usb-usbip.c
@@ -424,7 +424,7 @@ usbip_handle_data_urb (struct urb *urb)
   pthread_mutex_lock (&usbc_p->mutex);
   if (usbc_p->state == USB_STATE_DISABLED
       || usbc_p->state == USB_STATE_STALL)
-    r = -EAGAIN;
+    r = -EPIPE;
   else /* nak or ready */
     {
       if (usbc_p->urb == NULL)
@@ -689,8 +689,6 @@ usbip_handle_urb (uint32_t seq)
 	return;
     }
 
-  r = -r;
-
  leave:
   msg.cmd = htonl (REP_URB_SUBMIT);
   msg.seq = htonl (urb->seq);
@@ -1455,6 +1453,15 @@ usb_lld_shutdown (void)
   /* FIXME: Cancel all URB in the list here.  */
 }
 
+static void
+notify_hostcontroller (struct usb_control *usbc_p)
+{
+  const uint64_t l = 1;
+
+  write (usbc_p->eventfd, &l, sizeof (l));
+}
+
+
 #define USB_MAKE_EV(event) (event<<24)
 #define USB_MAKE_TXRX(ep_num,txrx,len) ((txrx? (1<<23):0)|(ep_num<<16)|len)
 
@@ -1490,7 +1497,6 @@ static void handle_datastage_out (struct usb_dev *dev)
 {
   struct ctrl_data *data_p = &dev->ctrl_data;
   uint32_t len;
-  const uint64_t l = 1;
 
   pthread_mutex_lock (&usbc_ep0.mutex);
   len = usbc_ep0.len;
@@ -1516,7 +1522,7 @@ static void handle_datastage_out (struct usb_dev *dev)
       usbc_ep0.state = USB_STATE_READY;
     }
 
-  write (usbc_ep0.eventfd, &l, sizeof (l));
+  notify_hostcontroller (&usbc_ep0);
   pthread_mutex_unlock (&usbc_ep0.mutex);
 }
 
@@ -1524,7 +1530,6 @@ static void handle_datastage_in (struct usb_dev *dev)
 {
   struct ctrl_data *data_p = &dev->ctrl_data;
   uint32_t len = USB_MAX_PACKET_SIZE;
-  const uint64_t l = 1;
 
   if ((data_p->len == 0) && (dev->state == LAST_IN_DATA))
     {
@@ -1548,7 +1553,7 @@ static void handle_datastage_in (struct usb_dev *dev)
 	  usbc_ep0.state = USB_STATE_READY;
 	}
 
-      write (usbc_ep0.eventfd, &l, sizeof (l));
+      notify_hostcontroller (&usbc_ep0);
       pthread_mutex_unlock (&usbc_ep0.mutex);
       return;
     }
@@ -1564,7 +1569,7 @@ static void handle_datastage_in (struct usb_dev *dev)
   usbc_ep0.state = USB_STATE_READY;
   data_p->len -= len;
   data_p->addr += len;
-  write (usbc_ep0.eventfd, &l, sizeof (l));
+  notify_hostcontroller (&usbc_ep0);
   pthread_mutex_unlock (&usbc_ep0.mutex);
 }
 
@@ -1887,7 +1892,6 @@ handle_setup0 (struct usb_dev *dev)
 static int handle_in0 (struct usb_dev *dev)
 {
   int r = 0;
-  const uint64_t l = 1;
 
   if (dev->state == IN_DATA || dev->state == LAST_IN_DATA)
     handle_datastage_in (dev);
@@ -1908,7 +1912,7 @@ static int handle_in0 (struct usb_dev *dev)
       usbc_ep0.buf = usb_setup;
       usbc_ep0.len = 8;
       usbc_ep0.state = USB_STATE_READY;
-      write (usbc_ep0.eventfd, &l, sizeof (l));
+      notify_hostcontroller (&usbc_ep0);
       pthread_mutex_unlock (&usbc_ep0.mutex);
     }
   else
@@ -1917,7 +1921,7 @@ static int handle_in0 (struct usb_dev *dev)
       dev->state = STALLED;
       pthread_mutex_lock (&usbc_ep0.mutex);
       usbc_ep0.state = USB_STATE_STALL;
-      write (usbc_ep0.eventfd, &l, sizeof (l));
+      notify_hostcontroller (&usbc_ep0);
       pthread_mutex_unlock (&usbc_ep0.mutex);
     }
 
@@ -1926,8 +1930,6 @@ static int handle_in0 (struct usb_dev *dev)
 
 static void handle_out0 (struct usb_dev *dev)
 {
-  const uint64_t l = 1;
-
   if (dev->state == OUT_DATA)
     /* Usual case.  */
     handle_datastage_out (dev);
@@ -1942,7 +1944,7 @@ static void handle_out0 (struct usb_dev *dev)
       usbc_ep0.buf = usb_setup;
       usbc_ep0.len = 8;
       usbc_ep0.state = USB_STATE_READY;
-      write (usbc_ep0.eventfd, &l, sizeof (l));
+      notify_hostcontroller (&usbc_ep0);
       pthread_mutex_unlock (&usbc_ep0.mutex);
     }
   else
@@ -1957,7 +1959,7 @@ static void handle_out0 (struct usb_dev *dev)
       dev->state = STALLED;
       pthread_mutex_lock (&usbc_ep0.mutex);
       usbc_ep0.state = USB_STATE_STALL;
-      write (usbc_ep0.eventfd, &l, sizeof (l));
+      notify_hostcontroller (&usbc_ep0);
       pthread_mutex_unlock (&usbc_ep0.mutex);
     }
 }
@@ -1998,14 +2000,12 @@ usb_handle_transfer (struct usb_dev *dev, uint8_t dir, uint8_t ep_num)
 int
 usb_lld_ctrl_ack (struct usb_dev *dev)
 {
-  const uint64_t l = 1;
-
   dev->state = WAIT_STATUS_IN;
   pthread_mutex_lock (&usbc_ep0.mutex);
   usbc_ep0.buf = usb_setup;
   usbc_ep0.len = 0;
   usbc_ep0.state = USB_STATE_READY;
-  write (usbc_ep0.eventfd, &l, sizeof (l));
+  notify_hostcontroller (&usbc_ep0);
   pthread_mutex_unlock (&usbc_ep0.mutex);
   return USB_EVENT_OK;
 }
@@ -2014,8 +2014,6 @@ int
 usb_lld_ctrl_recv (struct usb_dev *dev, void *p, size_t len)
 {
   struct ctrl_data *data_p = &dev->ctrl_data;
-  const uint64_t l = 1;
-
   data_p->addr = p;
   data_p->len = len;
   dev->state = OUT_DATA;
@@ -2025,7 +2023,7 @@ usb_lld_ctrl_recv (struct usb_dev *dev, void *p, size_t len)
   usbc_ep0.state = USB_STATE_READY;
   usbc_ep0.buf = p;
   usbc_ep0.len = len;
-  write (usbc_ep0.eventfd, &l, sizeof (l));
+  notify_hostcontroller (&usbc_ep0);
   pthread_mutex_unlock (&usbc_ep0.mutex);
   return USB_EVENT_OK;
 }
@@ -2036,7 +2034,6 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
   struct ctrl_data *data_p = &dev->ctrl_data;
   uint32_t len_asked = dev->dev_req.len;
   uint32_t len;
-  const uint64_t l = 1;
 
   data_p->addr = (void *)buf;
   data_p->len = buflen;
@@ -2065,7 +2062,7 @@ usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
   usbc_ep0.state = USB_STATE_READY;
   data_p->len -= len;
   data_p->addr += len;
-  write (usbc_ep0.eventfd, &l, sizeof (l));
+  notify_hostcontroller (&usbc_ep0);
   pthread_mutex_unlock (&usbc_ep0.mutex);
   return USB_EVENT_OK;
 }
@@ -2080,13 +2077,11 @@ usb_lld_current_configuration (struct usb_dev *dev)
 void
 usb_lld_ctrl_error (struct usb_dev *dev)
 {
-  const uint64_t l = 1;
-
   puts ("ctrl_error");
   dev->state = STALLED;
   pthread_mutex_lock (&usbc_ep0.mutex);
   usbc_ep0.state = USB_STATE_STALL;
-  write (usbc_ep0.eventfd, &l, sizeof (l));
+  notify_hostcontroller (&usbc_ep0);
   pthread_mutex_unlock (&usbc_ep0.mutex);
 }
 
@@ -2133,29 +2128,38 @@ usb_lld_setup_endp (struct usb_dev *dev, int ep_num, int rx_en, int tx_en)
 void
 usb_lld_stall_tx (int ep_num)
 {
+  struct usb_control *usbc_p = &usbc_ep_in[ep_num];
+
+  pthread_mutex_lock (&usbc_p->mutex);
+  usbc_p->state = USB_STATE_STALL;
+  notify_hostcontroller (usbc_p);
+  pthread_mutex_unlock (&usbc_p->mutex);
   printf ("stall tx %d\n", ep_num);
-  usbc_ep_in[ep_num].state = USB_STATE_STALL;
 }
 
 void
 usb_lld_stall_rx (int ep_num)
 {
+  struct usb_control *usbc_p = &usbc_ep_out[ep_num];
+
+  pthread_mutex_lock (&usbc_p->mutex);
+  usbc_p->state = USB_STATE_STALL;
+  notify_hostcontroller (usbc_p);
+  pthread_mutex_unlock (&usbc_p->mutex);
   printf ("stall rx %d\n", ep_num);
-  usbc_ep_out[ep_num].state = USB_STATE_STALL;
 }
 
 void
 usb_lld_rx_enable_buf (int ep_num, void *buf, size_t len)
 {
   struct usb_control *usbc_p = &usbc_ep_out[ep_num];
-  const uint64_t l = 1;
 
   pthread_mutex_lock (&usbc_p->mutex);
   usbc_p->state = USB_STATE_READY;
   usbc_p->buf = buf;
   usbc_p->len = len;
 
-  write (usbc_p->eventfd, &l, sizeof (l));
+  notify_hostcontroller (usbc_p);
   pthread_mutex_unlock (&usbc_p->mutex);
   printf ("usb_lld_rx_enable_buf: %d\n", ep_num);
 }
@@ -2165,13 +2169,12 @@ void
 usb_lld_tx_enable_buf (int ep_num, const void *buf, size_t len)
 {
   struct usb_control *usbc_p = &usbc_ep_in[ep_num];
-  const uint64_t l = 1;
 
   pthread_mutex_lock (&usbc_p->mutex);
   usbc_p->state = USB_STATE_READY;
   usbc_p->buf = (void *)buf;
   usbc_p->len = len;
-  write (usbc_p->eventfd, &l, sizeof (l));
+  notify_hostcontroller (usbc_p);
   pthread_mutex_unlock (&usbc_p->mutex);
   printf ("usb_lld_tx_enable_buf: %d %ld\n", ep_num, len);
 }
-- 
cgit v1.2.3