nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

Blame SOURCES/0150-Implement-USBDebug-full-USB-stack-variant.patch

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