]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Implement USBDebug (full USB stack variant).
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 1 Feb 2013 20:49:29 +0000 (21:49 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 1 Feb 2013 20:49:29 +0000 (21:49 +0100)
ChangeLog
grub-core/Makefile.core.def
grub-core/bus/usb/serial/common.c
grub-core/bus/usb/serial/ftdi.c
grub-core/bus/usb/serial/pl2303.c
grub-core/bus/usb/serial/usbdebug_late.c [new file with mode: 0644]
grub-core/bus/usb/usb.c
include/grub/usbdesc.h
include/grub/usbserial.h

index 4141f6a6363e2a6a93a9b08014e8649724037284..2e681c174c9cb0b10569e2118e08f0d0e583c843 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-02-01  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Implement USBDebug (full USB stack variant).
+
 2013-02-01  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/commands/lsacpi.c: Show more info. Hide some boring parts
index 4609a4b5d9f78f0632c4eb3f420138d80206f616..c006abfd3f6391fb4a134e399e88031340a4276c 100644 (file)
@@ -447,6 +447,12 @@ module = {
   enable = usb;
 };
 
+module = {
+  name = usbserial_usbdebug;
+  common = bus/usb/serial/usbdebug_late.c;
+  enable = usb;
+};
+
 module = {
   name = uhci;
   common = bus/usb/uhci.c;
index 953025963d3ef2402c803a5c49a9afadd61b36eb..06f2b0ea53aad0d7ed81d0df7bac07dae342e4c9 100644 (file)
@@ -42,7 +42,8 @@ static int usbnum = 0;
 
 int
 grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
-                      struct grub_serial_driver *driver)
+                      struct grub_serial_driver *driver, int in_endp,
+                      int out_endp)
 {
   struct grub_serial_port *port;
   int j;
@@ -73,12 +74,16 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
       struct grub_usb_desc_endp *endp;
       endp = &usbdev->config[0].interf[interfno].descendp[j];
 
-      if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+      if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2
+         && (in_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING
+             || in_endp == endp->endp_addr))
        {
          /* Bulk IN endpoint.  */
          port->in_endp = endp;
        }
-      else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+      else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2
+              && (out_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING
+                  || out_endp == endp->endp_addr))
        {
          /* Bulk OUT endpoint.  */
          port->out_endp = endp;
index 15ea8fb8959a95ab42fbdab5334031efdf0e2556..e94fd27fba1e899a8f4ac5a8c90975b37f6b85fe 100644 (file)
@@ -193,7 +193,9 @@ grub_ftdi_attach (grub_usb_device_t usbdev, int configno, int interfno)
     return 0;
 
   return grub_usbserial_attach (usbdev, configno, interfno,
-                               &grub_ftdi_driver);
+                               &grub_ftdi_driver,
+                               GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING,
+                               GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING);
 }
 
 static struct grub_usb_attach_desc attach_hook =
index 5433763e5fe20eeaf0d579c504f2719267e9bf4a..f46c6ac31caf18ad87bf367064c30f788ce5a6e3 100644 (file)
@@ -208,7 +208,9 @@ grub_pl2303_attach (grub_usb_device_t usbdev, int configno, int interfno)
     return 0;
 
   return grub_usbserial_attach (usbdev, configno, interfno,
-                               &grub_pl2303_driver);
+                               &grub_pl2303_driver,
+                               GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING,
+                               GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING);
 }
 
 static struct grub_usb_attach_desc attach_hook =
diff --git a/grub-core/bus/usb/serial/usbdebug_late.c b/grub-core/bus/usb/serial/usbdebug_late.c
new file mode 100644 (file)
index 0000000..23526e1
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010,2013  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/serial.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/usbserial.h>
+#include <grub/i18n.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+
+/* Fetch a key.  */
+static int
+usbdebug_late_hw_fetch (struct grub_serial_port *port)
+{
+  return grub_usbserial_fetch (port, 0);
+}
+
+/* Put a character.  */
+static void
+usbdebug_late_hw_put (struct grub_serial_port *port, const int c)
+{
+  char cc = c;
+
+  grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc);
+}
+
+static grub_err_t
+usbdebug_late_hw_configure (struct grub_serial_port *port __attribute__ ((unused)),
+                           struct grub_serial_config *config __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_serial_driver grub_usbdebug_late_driver =
+  {
+    .configure = usbdebug_late_hw_configure,
+    .fetch = usbdebug_late_hw_fetch,
+    .put = usbdebug_late_hw_put,
+    .fini = grub_usbserial_fini
+  };
+
+static int
+grub_usbdebug_late_attach (grub_usb_device_t usbdev, int configno, int interfno)
+{
+  grub_usb_err_t err;
+  struct grub_usb_desc_debug debugdesc;
+
+  err = grub_usb_get_descriptor (usbdev, GRUB_USB_DESCRIPTOR_DEBUG, configno,
+                                sizeof (debugdesc), (char *) &debugdesc);
+  if (err)
+    return 0;
+
+  return grub_usbserial_attach (usbdev, configno, interfno,
+                               &grub_usbdebug_late_driver,
+                               debugdesc.in_endp, debugdesc.out_endp);
+}
+
+static struct grub_usb_attach_desc attach_hook =
+{
+  .class = 0xff,
+  .hook = grub_usbdebug_late_attach
+};
+
+GRUB_MOD_INIT(usbserial_usbdebug_late)
+{
+  grub_usb_register_attach_hook_class (&attach_hook);
+}
+
+GRUB_MOD_FINI(usbserial_usbdebug_late)
+{
+  grub_serial_unregister_driver (&grub_usbdebug_late_driver);
+  grub_usb_unregister_attach_hook_class (&attach_hook);
+}
index 5df08e98d6fb751f843dffd228132344c9528fc0..41d8010ca281e3968f71109670b06c506e361454 100644 (file)
@@ -309,6 +309,8 @@ void grub_usb_device_attach (grub_usb_device_t dev)
          grub_print_error ();
          grub_dl_load ("usbserial_pl2303");
          grub_print_error ();
+         grub_dl_load ("usbserial_usbdebug");
+         grub_print_error ();
          break;
        }
     }
index 84b723a62dcb3c2c553ec7a9cf4bf73b3e311997..7d141524820423d438bd4f74d3e2e52da4139fe9 100644 (file)
@@ -28,6 +28,7 @@ typedef enum {
   GRUB_USB_DESCRIPTOR_STRING,
   GRUB_USB_DESCRIPTOR_INTERFACE,
   GRUB_USB_DESCRIPTOR_ENDPOINT,
+  GRUB_USB_DESCRIPTOR_DEBUG = 10,
   GRUB_USB_DESCRIPTOR_HUB = 0x29
 } grub_usb_descriptor_t;
 
@@ -111,6 +112,14 @@ struct grub_usb_desc_str
   grub_uint16_t str[0];
 } __attribute__ ((packed));
 
+struct grub_usb_desc_debug
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t in_endp;
+  grub_uint8_t out_endp;
+} __attribute__ ((packed));
+
 struct grub_usb_usb_hubdesc
 {
   grub_uint8_t length;
index 74201256e9ae4f0557a4fae9268d77616caa95a8..f81f97a51f630eb1f8a5881a342a80a2841809a1 100644 (file)
@@ -27,7 +27,12 @@ void grub_usbserial_detach (grub_usb_device_t usbdev, int configno,
 
 int
 grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
-                      struct grub_serial_driver *driver);
+                      struct grub_serial_driver *driver, int in_endp,
+                      int out_endp);
+enum
+  {
+    GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING = -1
+  };
 int
 grub_usbserial_fetch (struct grub_serial_port *port, grub_size_t header_size);