[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[1982] 2009-02-08 Marco Gerards <address@hidden>
From: |
Robert Millan |
Subject: |
[1982] 2009-02-08 Marco Gerards <address@hidden> |
Date: |
Sun, 08 Feb 2009 17:58:33 +0000 |
Revision: 1982
http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1982
Author: robertmh
Date: 2009-02-08 17:58:32 +0000 (Sun, 08 Feb 2009)
Log Message:
-----------
2009-02-08 Marco Gerards <address@hidden>
* Makefile.in (enable_grub_emu_usb): New variable.
* conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/scsi.c'.
(grub_emu_SOURCES) [grub_emu_SOURCES]: Add `disk/usbms.c',
`util/usb.c', `bus/usb/usb.c' and `commands/usbtest.c'.
(grub_emu_LDFLAGS): Add `$(LIBUSB)'.
(pkglib_MODULES): Add `usb.mod', `uhci.mod', `ohci.mod',
`usbtest.mod' and `usbms.mod'.
(usb_mod_SOURCES, usb_mod_CFLAGS, usb_mod_LDFLAGS)
(usbtest_mod_SOURCES, usbtest_mod_CFLAGS, usbtest_mod_LDFLAGS)
(uhci_mod_SOURCES, uhci_mod_CFLAGS, uhci_mod_LDFLAGS,
(ohci_mod_SOURCES, ohci_mod_CFLAGS, ohci_mod_LDFLAGS)
(usbms_mod_SOURCES, usbms_mod_CFLAGS, usbms_mod_LDFLAGS): New
variables.
* disk/usbms.c: New file.
* include/grub/usb.h: Likewise.
* include/grub/usbtrans.h: Likewise.
* include/grub/usbdesc.h: Likewise.
* bus/usb/usbtrans.c: Likewise.
* bus/usb/ohci.c: Likewise.
* bus/usb/uhci.c: Likewise.
* bus/usb/usbhub.c: Likewise.
* bus/usb/usb.c: Likewise.
* commands/usbtest.c: Likewise.
* util/usb.c: Likewise.
* include/grub/err.h (grub_err_t): Add `GRUB_ERR_IO'.
* configure.ac: Test for libusb presence.
* util/grub-emu.c (main) [HAVE_LIBUSB_H]: Call `grub_libusb_init'.
Modified Paths:
--------------
trunk/grub2/ChangeLog
trunk/grub2/DISTLIST
trunk/grub2/Makefile.in
trunk/grub2/conf/i386-pc.mk
trunk/grub2/conf/i386-pc.rmk
trunk/grub2/config.h.in
trunk/grub2/configure
trunk/grub2/configure.ac
trunk/grub2/include/grub/err.h
trunk/grub2/util/grub-emu.c
Added Paths:
-----------
trunk/grub2/bus/usb/
trunk/grub2/bus/usb/ohci.c
trunk/grub2/bus/usb/uhci.c
trunk/grub2/bus/usb/usb.c
trunk/grub2/bus/usb/usbhub.c
trunk/grub2/bus/usb/usbtrans.c
trunk/grub2/commands/usbtest.c
trunk/grub2/disk/usbms.c
trunk/grub2/include/grub/usb.h
trunk/grub2/include/grub/usbdesc.h
trunk/grub2/include/grub/usbtrans.h
trunk/grub2/util/usb.c
Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/ChangeLog 2009-02-08 17:58:32 UTC (rev 1982)
@@ -1,3 +1,47 @@
+2009-02-08 Marco Gerards <address@hidden>
+
+ * Makefile.in (enable_grub_emu_usb): New variable.
+ * conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/scsi.c'.
+ (grub_emu_SOURCES) [grub_emu_SOURCES]: Add `disk/usbms.c',
+ `util/usb.c', `bus/usb/usb.c' and `commands/usbtest.c'.
+ (grub_emu_LDFLAGS): Add `$(LIBUSB)'.
+ (pkglib_MODULES): Add `usb.mod', `uhci.mod', `ohci.mod',
+ `usbtest.mod' and `usbms.mod'.
+ (usb_mod_SOURCES, usb_mod_CFLAGS, usb_mod_LDFLAGS)
+ (usbtest_mod_SOURCES, usbtest_mod_CFLAGS, usbtest_mod_LDFLAGS)
+ (uhci_mod_SOURCES, uhci_mod_CFLAGS, uhci_mod_LDFLAGS,
+ (ohci_mod_SOURCES, ohci_mod_CFLAGS, ohci_mod_LDFLAGS)
+ (usbms_mod_SOURCES, usbms_mod_CFLAGS, usbms_mod_LDFLAGS): New
+ variables.
+
+ * disk/usbms.c: New file.
+
+ * include/grub/usb.h: Likewise.
+
+ * include/grub/usbtrans.h: Likewise.
+
+ * include/grub/usbdesc.h: Likewise.
+
+ * bus/usb/usbtrans.c: Likewise.
+
+ * bus/usb/ohci.c: Likewise.
+
+ * bus/usb/uhci.c: Likewise.
+
+ * bus/usb/usbhub.c: Likewise.
+
+ * bus/usb/usb.c: Likewise.
+
+ * commands/usbtest.c: Likewise.
+
+ * util/usb.c: Likewise.
+
+ * include/grub/err.h (grub_err_t): Add `GRUB_ERR_IO'.
+
+ * configure.ac: Test for libusb presence.
+
+ * util/grub-emu.c (main) [HAVE_LIBUSB_H]: Call `grub_libusb_init'.
+
2009-02-08 Vesa Jääskeläinen <address@hidden>
* kern/mm.c: Add more comments.
Modified: trunk/grub2/DISTLIST
===================================================================
--- trunk/grub2/DISTLIST 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/DISTLIST 2009-02-08 17:58:32 UTC (rev 1982)
@@ -35,6 +35,11 @@
boot/i386/pc/lnxboot.S
boot/i386/pc/pxeboot.S
bus/pci.c
+bus/usb/ohci.c
+bus/usb/uhci.c
+bus/usb/usb.c
+bus/usb/usbhub.c
+bus/usb/usbtrans.c
commands/blocklist.c
commands/boot.c
commands/cat.c
@@ -56,6 +61,7 @@
commands/sleep.c
commands/terminal.c
commands/test.c
+commands/usbtest.c
commands/videotest.c
commands/i386/cpuid.c
commands/i386/pc/halt.c
@@ -95,6 +101,7 @@
disk/raid5_recover.c
disk/raid6_recover.c
disk/scsi.c
+disk/usbms.c
disk/efi/efidisk.c
disk/i386/pc/biosdisk.c
disk/ieee1275/nand.c
@@ -179,6 +186,9 @@
include/grub/time.h
include/grub/tparm.h
include/grub/types.h
+include/grub/usb.h
+include/grub/usbdesc.h
+include/grub/usbtrans.h
include/grub/video.h
include/grub/efi/api.h
include/grub/efi/chainloader.h
@@ -438,6 +448,7 @@
util/raid.c
util/resolve.c
util/update-grub_lib.in
+util/usb.c
util/elf/grub-mkimage.c
util/grub.d/00_header.in
util/grub.d/10_freebsd.in
Modified: trunk/grub2/Makefile.in
===================================================================
--- trunk/grub2/Makefile.in 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/Makefile.in 2009-02-08 17:58:32 UTC (rev 1982)
@@ -92,6 +92,7 @@
# Options.
enable_grub_emu = @enable_grub_emu@
+enable_grub_emu_usb = @enable_grub_emu_usb@
enable_grub_fstest = @enable_grub_fstest@
enable_grub_pe2elf = @enable_grub_pe2elf@
enable_lzo = @enable_lzo@
Added: trunk/grub2/bus/usb/ohci.c
===================================================================
--- trunk/grub2/bus/usb/ohci.c (rev 0)
+++ trunk/grub2/bus/usb/ohci.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,608 @@
+/* ohci.c - OHCI Support. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+#include <grub/misc.h>
+#include <grub/pci.h>
+#include <grub/cpu/pci.h>
+#include <grub/i386/io.h>
+#include <grub/time.h>
+
+struct grub_ohci_hcca
+{
+ /* Pointers to Interrupt Endpoint Descriptors. Not used by
+ GRUB. */
+ grub_uint32_t inttable[32];
+
+ /* Current frame number. */
+ grub_uint16_t framenumber;
+
+ grub_uint16_t pad;
+
+ /* List of completed TDs. */
+ grub_uint32_t donehead;
+
+ grub_uint8_t reserved[116];
+} __attribute__((packed));
+
+/* OHCI Endpoint Descriptor. */
+struct grub_ohci_ed
+{
+ grub_uint32_t target;
+ grub_uint32_t td_tail;
+ grub_uint32_t td_head;
+ grub_uint32_t next_ed;
+} __attribute__((packed));
+
+struct grub_ohci_td
+{
+ /* Information used to construct the TOKEN packet. */
+ grub_uint32_t token;
+
+ grub_uint32_t buffer;
+ grub_uint32_t next_td;
+ grub_uint32_t buffer_end;
+} __attribute__((packed));
+
+typedef struct grub_ohci_td *grub_ohci_td_t;
+typedef struct grub_ohci_ed *grub_ohci_ed_t;
+
+struct grub_ohci
+{
+ volatile grub_uint32_t *iobase;
+ volatile struct grub_ohci_hcca *hcca;
+ struct grub_ohci *next;
+};
+
+static struct grub_ohci *ohci;
+
+typedef enum
+{
+ GRUB_OHCI_REG_REVISION = 0x00,
+ GRUB_OHCI_REG_CONTROL,
+ GRUB_OHCI_REG_CMDSTATUS,
+ GRUB_OHCI_REG_INTSTATUS,
+ GRUB_OHCI_REG_INTENA,
+ GRUB_OHCI_REG_INTDIS,
+ GRUB_OHCI_REG_HCCA,
+ GRUB_OHCI_REG_PERIODIC,
+ GRUB_OHCI_REG_CONTROLHEAD,
+ GRUB_OHCI_REG_CONTROLCURR,
+ GRUB_OHCI_REG_BULKHEAD,
+ GRUB_OHCI_REG_BULKCURR,
+ GRUB_OHCI_REG_DONEHEAD,
+ GRUB_OHCI_REG_FRAME_INTERVAL,
+ GRUB_OHCI_REG_RHUBA = 18,
+ GRUB_OHCI_REG_RHUBPORT = 21
+} grub_ohci_reg_t;
+
+static grub_uint32_t
+grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg)
+{
+ return grub_le_to_cpu32 (*(o->iobase + reg));
+}
+
+static void
+grub_ohci_writereg32 (struct grub_ohci *o,
+ grub_ohci_reg_t reg, grub_uint32_t val)
+{
+ *(o->iobase + reg) = grub_cpu_to_le32 (val);
+}
+
+
+
+/* Iterate over all PCI devices. Determine if a device is an OHCI
+ controller. If this is the case, initialize it. */
+static int grub_ohci_pci_iter (int bus, int device, int func,
+ grub_pci_id_t pciid __attribute__((unused)))
+{
+ grub_uint32_t class;
+ grub_uint32_t subclass;
+ int interf;
+ grub_uint32_t base;
+ grub_pci_address_t addr;
+ struct grub_ohci *o;
+ grub_uint32_t revision;
+ grub_uint32_t frame_interval;
+
+ addr = grub_pci_make_address (bus, device, func, 2);
+ class = grub_pci_read (addr);
+ addr = grub_pci_make_address (bus, device, func, 2);
+ class = grub_pci_read (addr);
+
+ interf = class & 0xFF;
+ subclass = (class >> 16) & 0xFF;
+ class >>= 24;
+
+ /* If this is not an OHCI controller, just return. */
+ if (class != 0x0c || subclass != 0x03)
+ return 0;
+
+ /* Determine IO base address. */
+ addr = grub_pci_make_address (bus, device, func, 4);
+ base = grub_pci_read (addr);
+
+#if 0
+ /* Stop if there is no IO space base address defined. */
+ if (! (base & 1))
+ return 0;
+#endif
+
+ /* Allocate memory for the controller and register it. */
+ o = grub_malloc (sizeof (*o));
+ if (! o)
+ return 1;
+
+ /* Link in the OHCI. */
+ o->next = ohci;
+ ohci = o;
+ o->iobase = (grub_uint32_t *) base;
+
+ /* Reserve memory for the HCCA. */
+ o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256);
+
+ /* Check if the OHCI revision is actually 1.0 as supported. */
+ revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION);
+ grub_dprintf ("ohci", "OHCI revision=0x%02x\n", revision & 0xFF);
+ if ((revision & 0xFF) != 0x10)
+ goto fail;
+
+ /* Backup the frame interval register. */
+ frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL);
+
+ /* Suspend the OHCI by issuing a reset. */
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic.
+ */
+ grub_millisleep (1);
+ grub_dprintf ("ohci", "OHCI reset\n");
+
+ /* Restore the frame interval register. */
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval);
+
+ /* Setup the HCCA. */
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca);
+ grub_dprintf ("ohci", "OHCI HCCA\n");
+
+ /* Enable the OHCI. */
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
+ (2 << 6));
+ grub_dprintf ("ohci", "OHCI enable: 0x%02x\n",
+ (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3);
+
+ return 0;
+
+ fail:
+ if (o)
+ grub_free ((void *) o->hcca);
+ grub_free (o);
+
+ return 1;
+}
+
+
+static void
+grub_ohci_inithw (void)
+{
+ grub_pci_iterate (grub_ohci_pci_iter);
+}
+
+
+
+static int
+grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+ struct grub_ohci *o;
+ struct grub_usb_controller dev;
+
+ for (o = ohci; o; o = o->next)
+ {
+ dev.data = o;
+ if (hook (&dev))
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+grub_ohci_transaction (grub_ohci_td_t td,
+ grub_transfer_type_t type, unsigned int toggle,
+ grub_size_t size, char *data)
+{
+ grub_uint32_t token;
+ grub_uint32_t buffer;
+ grub_uint32_t buffer_end;
+
+ grub_dprintf ("ohci", "OHCI transaction td=0x%02x type=%d, toggle=%d,
size=%d\n",
+ td, type, toggle, size);
+
+ switch (type)
+ {
+ case GRUB_USB_TRANSFER_TYPE_SETUP:
+ token = 0 << 19;
+ break;
+ case GRUB_USB_TRANSFER_TYPE_IN:
+ token = 2 << 19;
+ break;
+ case GRUB_USB_TRANSFER_TYPE_OUT:
+ token = 1 << 19;
+ break;
+ default:
+ token = 0;
+ break;
+ }
+
+ /* Generate no interrupts. */
+ token |= 7 << 21;
+
+ /* Set the token. */
+ token |= toggle << 24;
+ token |= 1 << 25;
+
+ buffer = (grub_uint32_t) data;
+ buffer_end = buffer + size - 1;
+
+ td->token = grub_cpu_to_le32 (token);
+ td->buffer = grub_cpu_to_le32 (buffer);
+ td->next_td = 0;
+ td->buffer_end = grub_cpu_to_le32 (buffer_end);
+}
+
+static grub_usb_err_t
+grub_ohci_transfer (grub_usb_controller_t dev,
+ grub_usb_transfer_t transfer)
+{
+ struct grub_ohci *o = (struct grub_ohci *) dev->data;
+ grub_ohci_ed_t ed;
+ grub_ohci_td_t td_list;
+ grub_uint32_t target;
+ grub_uint32_t td_tail;
+ grub_uint32_t td_head;
+ grub_uint32_t status;
+ grub_uint32_t control;
+ grub_usb_err_t err;
+ int i;
+
+ /* Allocate an Endpoint Descriptor. */
+ ed = grub_memalign (16, sizeof (*ed));
+ if (! ed)
+ return GRUB_USB_ERR_INTERNAL;
+
+ td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1));
+ if (! td_list)
+ {
+ grub_free ((void *) ed);
+ return GRUB_USB_ERR_INTERNAL;
+ }
+
+ grub_dprintf ("ohci", "alloc=0x%08x\n", td_list);
+
+ /* Setup all Transfer Descriptors. */
+ for (i = 0; i < transfer->transcnt; i++)
+ {
+ grub_usb_transaction_t tr = &transfer->transactions[i];
+
+ grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle,
+ tr->size, tr->data);
+
+ td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]);
+ }
+
+ /* Setup the Endpoint Descriptor. */
+
+ /* Set the device address. */
+ target = transfer->devaddr;
+
+ /* Set the endpoint. */
+ target |= transfer->endpoint << 7;
+
+ /* Set the device speed. */
+ target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13;
+
+ /* Set the maximum packet size. */
+ target |= transfer->max << 16;
+
+ td_head = (grub_uint32_t) td_list;
+
+ td_tail = (grub_uint32_t) &td_list[transfer->transcnt];
+
+ ed->target = grub_cpu_to_le32 (target);
+ ed->td_head = grub_cpu_to_le32 (td_head);
+ ed->td_tail = grub_cpu_to_le32 (td_tail);
+ ed->next_ed = grub_cpu_to_le32 (0);
+
+ grub_dprintf ("ohci", "program OHCI\n");
+
+ /* Program the OHCI to actually transfer. */
+ switch (transfer->type)
+ {
+ case GRUB_USB_TRANSACTION_TYPE_BULK:
+ {
+ grub_dprintf ("ohci", "add to bulk list\n");
+
+ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+ control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+
+ /* Disable the Control and Bulk lists. */
+ control &= ~(3 << 4);
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+ /* Clear BulkListFilled. */
+ status &= ~(1 << 2);
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed);
+
+ /* Enable the Bulk list. */
+ control |= 1 << 5;
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+ /* Set BulkListFilled. */
+ status |= 1 << 2;
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+ break;
+ }
+
+ case GRUB_USB_TRANSACTION_TYPE_CONTROL:
+ {
+ grub_dprintf ("ohci", "add to control list\n");
+ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+ control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+
+ /* Disable the Control and Bulk lists. */
+ control &= ~(3 << 4);
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+ /* Clear ControlListFilled. */
+ status &= ~(1 << 1);
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD,
+ (grub_uint32_t) ed);
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1,
+ (grub_uint32_t) ed);
+
+ /* Enable the Control list. */
+ control |= 1 << 4;
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+ /* Set ControlListFilled. */
+ status |= 1 << 1;
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+ break;
+ }
+ }
+
+ grub_dprintf ("ohci", "wait for completion\n");
+ grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n",
+ grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL),
+ grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS));
+
+ /* Wait until the transfer is completed or STALLs. */
+ while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf))
+ {
+ grub_cpu_idle ();
+
+ grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head,
ed->td_tail);
+
+ /* Detected a STALL. */
+ if (ed->td_head & 1)
+ break;
+ }
+
+ grub_dprintf ("ohci", "complete\n");
+
+/* if (ed->td_head & 1) */
+/* err = GRUB_USB_ERR_STALL; */
+/* else if (ed->td */
+
+
+ if (ed->td_head & 1)
+ {
+ grub_uint8_t errcode;
+ grub_ohci_td_t tderr;
+
+ tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o,
+ GRUB_OHCI_REG_DONEHEAD);
+ errcode = tderr->token >> 28;
+
+ switch (errcode)
+ {
+ case 0:
+ /* XXX: Should not happen! */
+ grub_error (GRUB_ERR_IO, "OHCI without reporting the reason");
+ err = GRUB_USB_ERR_INTERNAL;
+ break;
+
+ case 1:
+ /* XXX: CRC error. */
+ err = GRUB_USB_ERR_TIMEOUT;
+ break;
+
+ case 2:
+ err = GRUB_USB_ERR_BITSTUFF;
+ break;
+
+ case 3:
+ /* XXX: Data Toggle error. */
+ err = GRUB_USB_ERR_DATA;
+ break;
+
+ case 4:
+ err = GRUB_USB_ERR_STALL;
+ break;
+
+ case 5:
+ /* XXX: Not responding. */
+ err = GRUB_USB_ERR_TIMEOUT;
+ break;
+
+ case 6:
+ /* XXX: PID Check bits failed. */
+ err = GRUB_USB_ERR_BABBLE;
+ break;
+
+ case 7:
+ /* XXX: PID unexpected failed. */
+ err = GRUB_USB_ERR_BABBLE;
+ break;
+
+ case 8:
+ /* XXX: Data overrun error. */
+ err = GRUB_USB_ERR_DATA;
+ break;
+
+ case 9:
+ /* XXX: Data underrun error. */
+ err = GRUB_USB_ERR_DATA;
+ break;
+
+ case 10:
+ /* XXX: Reserved. */
+ err = GRUB_USB_ERR_NAK;
+ break;
+
+ case 11:
+ /* XXX: Reserved. */
+ err = GRUB_USB_ERR_NAK;
+ break;
+
+ case 12:
+ /* XXX: Buffer overrun. */
+ err = GRUB_USB_ERR_DATA;
+ break;
+
+ case 13:
+ /* XXX: Buffer underrun. */
+ err = GRUB_USB_ERR_DATA;
+ break;
+
+ default:
+ err = GRUB_USB_ERR_NAK;
+ break;
+ }
+ }
+ else
+ err = GRUB_USB_ERR_NONE;
+
+ /* Disable the Control and Bulk lists. */
+ control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+ control &= ~(3 << 4);
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+ /* Clear BulkListFilled and ControlListFilled. */
+ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+ status &= ~((1 << 2) | (1 << 3));
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+ /* XXX */
+ grub_free (td_list);
+ grub_free (ed);
+
+ return err;
+}
+
+static grub_err_t
+grub_ohci_portstatus (grub_usb_controller_t dev,
+ unsigned int port, unsigned int enable)
+{
+ struct grub_ohci *o = (struct grub_ohci *) dev->data;
+ grub_uint32_t status;
+
+ /* Reset the port. */
+ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+ status |= (1 << 4); /* XXX: Magic. */
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+ grub_millisleep (100);
+
+ /* End the reset signaling. */
+ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+ status |= (1 << 20); /* XXX: Magic. */
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+ grub_millisleep (10);
+
+ /* Enable the port. */
+ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+ status |= (enable << 1); /* XXX: Magic. */
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+
+ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+ grub_dprintf ("ohci", "portstatus=0x%02x\n", status);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_usb_speed_t
+grub_ohci_detect_dev (grub_usb_controller_t dev, int port)
+{
+ struct grub_ohci *o = (struct grub_ohci *) dev->data;
+ grub_uint32_t status;
+
+ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+
+ grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status);
+
+ if (! (status & 1))
+ return GRUB_USB_SPEED_NONE;
+ else if (status & (1 << 9))
+ return GRUB_USB_SPEED_LOW;
+ else
+ return GRUB_USB_SPEED_FULL;
+}
+
+static int
+grub_ohci_hubports (grub_usb_controller_t dev)
+{
+ struct grub_ohci *o = (struct grub_ohci *) dev->data;
+ grub_uint32_t portinfo;
+
+ portinfo = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA);
+
+ grub_dprintf ("ohci", "root hub ports=%d\n", portinfo & 0xFF);
+
+ /* The root hub has exactly two ports. */
+ return portinfo & 0xFF;
+}
+
+
+
+static struct grub_usb_controller_dev usb_controller =
+{
+ .name = "ohci",
+ .iterate = grub_ohci_iterate,
+ .transfer = grub_ohci_transfer,
+ .hubports = grub_ohci_hubports,
+ .portstatus = grub_ohci_portstatus,
+ .detect_dev = grub_ohci_detect_dev
+};
+
+GRUB_MOD_INIT(ohci)
+{
+ grub_ohci_inithw ();
+ grub_usb_controller_dev_register (&usb_controller);
+}
+
+GRUB_MOD_FINI(ohci)
+{
+ grub_usb_controller_dev_unregister (&usb_controller);
+}
Added: trunk/grub2/bus/usb/uhci.c
===================================================================
--- trunk/grub2/bus/usb/uhci.c (rev 0)
+++ trunk/grub2/bus/usb/uhci.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,675 @@
+/* uhci.c - UHCI Support. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+#include <grub/pci.h>
+#include <grub/cpu/pci.h>
+#include <grub/i386/io.h>
+#include <grub/time.h>
+
+#define GRUB_UHCI_IOMASK (0x7FF << 5)
+
+typedef enum
+ {
+ GRUB_UHCI_REG_USBCMD = 0x00,
+ GRUB_UHCI_REG_FLBASEADD = 0x08,
+ GRUB_UHCI_REG_PORTSC1 = 0x10,
+ GRUB_UHCI_REG_PORTSC2 = 0x12
+ } grub_uhci_reg_t;
+
+#define GRUB_UHCI_LINK_TERMINATE 1
+#define GRUB_UHCI_LINK_QUEUE_HEAD 2
+
+
+/* UHCI Queue Head. */
+struct grub_uhci_qh
+{
+ /* Queue head link pointer which points to the next queue head. */
+ grub_uint32_t linkptr;
+
+ /* Queue element link pointer which points to the first data object
+ within the queue. */
+ grub_uint32_t elinkptr;
+
+ /* Queue heads are aligned on 16 bytes, pad so a queue head is 16
+ bytes so we can store many in a 4K page. */
+ grub_uint8_t pad[8];
+} __attribute__ ((packed));
+
+/* UHCI Tranfer Descriptor. */
+struct grub_uhci_td
+{
+ /* Pointer to the next TD in the list. */
+ grub_uint32_t linkptr;
+
+ /* Control and status bits. */
+ grub_uint32_t ctrl_status;
+
+ /* All information required to transfer the Token packet. */
+ grub_uint32_t token;
+
+ /* A pointer to the data buffer, UHCI requires this pointer to be 32
+ bits. */
+ grub_uint32_t buffer;
+
+ /* Another linkptr that is not overwritten by the Host Controller.
+ This is GRUB specific. */
+ grub_uint32_t linkptr2;
+
+ /* 3 additional 32 bits words reserved for the Host Controller Driver. */
+ grub_uint32_t data[3];
+} __attribute__ ((packed));
+
+typedef volatile struct grub_uhci_td *grub_uhci_td_t;
+typedef volatile struct grub_uhci_qh *grub_uhci_qh_t;
+
+struct grub_uhci
+{
+ int iobase;
+ grub_uint32_t *framelist;
+
+ /* 256 Queue Heads. */
+ grub_uhci_qh_t qh;
+
+ /* 256 Transfer Descriptors. */
+ grub_uhci_td_t td;
+
+ /* Free Transfer Descriptors. */
+ grub_uhci_td_t tdfree;
+
+ struct grub_uhci *next;
+};
+
+static struct grub_uhci *uhci;
+
+static grub_uint16_t
+grub_uhci_readreg16 (struct grub_uhci *u, grub_uhci_reg_t reg)
+{
+ return grub_inw (u->iobase + reg);
+}
+
+#if 0
+static grub_uint32_t
+grub_uhci_readreg32 (struct grub_uhci *u, grub_uhci_reg_t reg)
+{
+ return grub_inl (u->iobase + reg);
+}
+#endif
+
+static void
+grub_uhci_writereg16 (struct grub_uhci *u,
+ grub_uhci_reg_t reg, grub_uint16_t val)
+{
+ grub_outw (val, u->iobase + reg);
+}
+
+static void
+grub_uhci_writereg32 (struct grub_uhci *u,
+ grub_uhci_reg_t reg, grub_uint32_t val)
+{
+ grub_outl (val, u->iobase + reg);
+}
+
+static grub_err_t
+grub_uhci_portstatus (grub_usb_controller_t dev,
+ unsigned int port, unsigned int enable);
+
+
+/* Iterate over all PCI devices. Determine if a device is an UHCI
+ controller. If this is the case, initialize it. */
+static int grub_uhci_pci_iter (int bus, int device, int func,
+ grub_pci_id_t pciid __attribute__((unused)))
+{
+ grub_uint32_t class;
+ grub_uint32_t subclass;
+ grub_uint32_t base;
+ grub_uint32_t fp;
+ grub_pci_address_t addr;
+ struct grub_uhci *u;
+ int i;
+
+ addr = grub_pci_make_address (bus, device, func, 2);
+ class = grub_pci_read (addr);
+ addr = grub_pci_make_address (bus, device, func, 2);
+ class = grub_pci_read (addr);
+
+ subclass = (class >> 16) & 0xFF;
+ class >>= 24;
+
+ /* If this is not an UHCI controller, just return. */
+ if (class != 0x0c || subclass != 0x03)
+ return 0;
+
+ /* Determine IO base address. */
+ addr = grub_pci_make_address (bus, device, func, 8);
+ base = grub_pci_read (addr);
+ /* Stop if there is no IO space base address defined. */
+ if (! (base & 1))
+ return 0;
+
+ /* Allocate memory for the controller and register it. */
+ u = grub_malloc (sizeof (*u));
+ if (! u)
+ return 1;
+
+ u->next = uhci;
+ uhci = u;
+ u->iobase = base & GRUB_UHCI_IOMASK;
+ u->framelist = 0;
+ u->qh = 0;
+ u->td = 0;
+ grub_dprintf ("uhci", "class=0x%02x 0x%02x base=0x%x\n",
+ class, subclass, u->iobase);
+
+ /* Reserve a page for the frame list. */
+ u->framelist = grub_memalign (4096, 4096);
+ if (! u->framelist)
+ goto fail;
+
+ /* The framelist pointer of UHCI is only 32 bits, make sure this
+ code works on on 64 bits architectures. */
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+ if ((grub_uint64_t) u->framelist >> 32)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "allocated frame list memory not <4GB");
+ goto fail;
+ }
+#endif
+
+ /* The QH pointer of UHCI is only 32 bits, make sure this
+ code works on on 64 bits architectures. */
+ u->qh = (grub_uhci_qh_t) grub_memalign (4096, 4096);
+ if (! u->qh)
+ goto fail;
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+ if ((grub_uint64_t) u->qh >> 32)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated QH memory not <4GB");
+ goto fail;
+ }
+#endif
+
+ /* The TD pointer of UHCI is only 32 bits, make sure this
+ code works on on 64 bits architectures. */
+ u->td = (grub_uhci_td_t) grub_memalign (4096, 4096*2);
+ if (! u->td)
+ goto fail;
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+ if ((grub_uint64_t) u->td >> 32)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated TD memory not <4GB");
+ goto fail;
+ }
+#endif
+
+ /* Link all Transfer Descriptors in a list of available Transfer
+ Descriptors. */
+ for (i = 0; i < 256; i++)
+ u->td[i].linkptr = (grub_uint32_t) &u->td[i + 1];
+ u->td[255 - 1].linkptr = 0;
+ u->tdfree = u->td;
+
+ /* Make sure UHCI is disabled! */
+ grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
+
+ /* Setup the frame list pointers. Since no isochronous transfers
+ are and will be supported, they all point to the (same!) queue
+ head. */
+ fp = (grub_uint32_t) u->qh & (~15);
+ /* Mark this as a queue head. */
+ fp |= 2;
+ for (i = 0; i < 1024; i++)
+ u->framelist[i] = fp;
+ /* Program the framelist address into the UHCI controller. */
+ grub_uhci_writereg32 (u, GRUB_UHCI_REG_FLBASEADD,
+ (grub_uint32_t) u->framelist);
+
+ /* Make the Queue Heads point to eachother. */
+ for (i = 0; i < 256; i++)
+ {
+ /* Point to the next QH. */
+ u->qh[i].linkptr = (grub_uint32_t) (&u->qh[i + 1]) & (~15);
+
+ /* This is a QH. */
+ u->qh[i].linkptr |= GRUB_UHCI_LINK_QUEUE_HEAD;
+
+ /* For the moment, do not point to a Transfer Descriptor. These
+ are set at transfer time, so just terminate it. */
+ u->qh[i].elinkptr = 1;
+ }
+
+ /* The last Queue Head should terminate. 256 are too many QHs so
+ just use 50. */
+ u->qh[50 - 1].linkptr = 1;
+
+ /* Enable UHCI again. */
+ grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7));
+
+ /* UHCI is initialized and ready for transfers. */
+ grub_dprintf ("uhci", "UHCI initialized\n");
+
+
+#if 0
+ {
+ int i;
+ for (i = 0; i < 10; i++)
+ {
+ grub_uint16_t frnum;
+
+ frnum = grub_uhci_readreg16 (u, 6);
+ grub_dprintf ("uhci", "Framenum=%d\n", frnum);
+ grub_millisleep (100);
+ }
+ }
+#endif
+
+ return 0;
+
+ fail:
+ if (u)
+ {
+ grub_free ((void *) u->qh);
+ grub_free (u->framelist);
+ }
+ grub_free (u);
+
+ return 1;
+}
+
+static void
+grub_uhci_inithw (void)
+{
+ grub_pci_iterate (grub_uhci_pci_iter);
+}
+
+static grub_uhci_td_t
+grub_alloc_td (struct grub_uhci *u)
+{
+ grub_uhci_td_t ret;
+
+ /* Check if there is a Transfer Descriptor available. */
+ if (! u->tdfree)
+ return NULL;
+
+ ret = u->tdfree;
+ u->tdfree = (grub_uhci_td_t) u->tdfree->linkptr;
+
+ return ret;
+}
+
+static void
+grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
+{
+ td->linkptr = (grub_uint32_t) u->tdfree;
+ u->tdfree = td;
+}
+
+static void
+grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td)
+{
+ /* Free the TDs in this queue. */
+ while (td)
+ {
+ grub_uhci_td_t tdprev;
+
+ /* Unlink the queue. */
+ tdprev = td;
+ td = (grub_uhci_td_t) td->linkptr2;
+
+ /* Free the TD. */
+ grub_free_td (u, tdprev);
+ }
+}
+
+static grub_uhci_qh_t
+grub_alloc_qh (struct grub_uhci *u,
+ grub_transaction_type_t tr __attribute__((unused)))
+{
+ int i;
+ grub_uhci_qh_t qh;
+
+ /* Look for a Queue Head for this transfer. Skip the first QH if
+ this is a Interrupt Transfer. */
+#if 0
+ if (tr == GRUB_USB_TRANSACTION_TYPE_INTERRUPT)
+ i = 0;
+ else
+#endif
+ i = 1;
+
+ for (; i < 255; i++)
+ {
+ if (u->qh[i].elinkptr & 1)
+ break;
+ }
+ qh = &u->qh[i];
+ if (! (qh->elinkptr & 1))
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "no free queue heads available");
+ return NULL;
+ }
+
+ return qh;
+}
+
+static grub_uhci_td_t
+grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
+ grub_transfer_type_t type, unsigned int addr,
+ unsigned int toggle, grub_size_t size,
+ char *data)
+{
+ grub_uhci_td_t td;
+ static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
+
+ /* XXX: Check if data is <4GB. If it isn't, just copy stuff around.
+ This is only relevant for 64 bits architectures. */
+
+ /* Grab a free Transfer Descriptor and initialize it. */
+ td = grub_alloc_td (u);
+ if (! td)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "no transfer descriptors available for UHCI transfer");
+ return 0;
+ }
+
+ grub_dprintf ("uhci",
+ "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d
data=%p td=%p\n",
+ endp, type, addr, toggle, size, data, td);
+
+ /* Don't point to any TD, just terminate. */
+ td->linkptr = 1;
+
+ /* Active! Only retry a transfer 3 times. */
+ td->ctrl_status = (1 << 23) | (3 << 27);
+
+ /* If zero bytes are transmitted, size is 0x7FF. Otherwise size is
+ size-1. */
+ if (size == 0)
+ size = 0x7FF;
+ else
+ size = size - 1;
+
+ /* Setup whatever is required for the token packet. */
+ td->token = ((size << 21) | (toggle << 19) | (endp << 15)
+ | (addr << 8) | tf[type]);
+
+ td->buffer = (grub_uint32_t) data;
+
+ return td;
+}
+
+static grub_usb_err_t
+grub_uhci_transfer (grub_usb_controller_t dev,
+ grub_usb_transfer_t transfer)
+{
+ struct grub_uhci *u = (struct grub_uhci *) dev->data;
+ grub_uhci_qh_t qh;
+ grub_uhci_td_t td;
+ grub_uhci_td_t td_first = NULL;
+ grub_uhci_td_t td_prev = NULL;
+ grub_usb_err_t err = GRUB_USB_ERR_NONE;
+ int i;
+
+ /* Allocate a queue head for the transfer queue. */
+ qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
+ if (! qh)
+ return grub_errno;
+
+ for (i = 0; i < transfer->transcnt; i++)
+ {
+ grub_usb_transaction_t tr = &transfer->transactions[i];
+
+ td = grub_uhci_transaction (u, transfer->endpoint, tr->pid,
+ transfer->devaddr, tr->toggle,
+ tr->size, tr->data);
+ if (! td)
+ {
+ /* Terminate and free. */
+ td_prev->linkptr2 = 0;
+ td_prev->linkptr = 1;
+
+ if (td_first)
+ grub_free_queue (u, td_first);
+
+ return GRUB_USB_ERR_INTERNAL;
+ }
+
+ if (! td_first)
+ td_first = td;
+ else
+ {
+ td_prev->linkptr2 = (grub_uint32_t) td;
+ td_prev->linkptr = (grub_uint32_t) td;
+ td_prev->linkptr |= 4;
+ }
+ td_prev = td;
+ }
+ td_prev->linkptr2 = 0;
+ td_prev->linkptr = 1;
+
+ grub_dprintf ("uhci", "setup transaction %d\n", transfer->type);
+
+ /* Link it into the queue and terminate. Now the transaction can
+ take place. */
+ qh->elinkptr = (grub_uint32_t) td_first;
+
+ grub_dprintf ("uhci", "initiate transaction\n");
+
+ /* Wait until either the transaction completed or an error
+ occured. */
+ for (;;)
+ {
+ grub_uhci_td_t errtd;
+
+ errtd = (grub_uhci_td_t) (qh->elinkptr & ~0x0f);
+
+ grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
+ errtd->ctrl_status, errtd->buffer & (~15), errtd);
+
+ /* Check if the transaction completed. */
+ if (qh->elinkptr & 1)
+ break;
+
+ grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
+
+ /* Check if the TD is not longer active. */
+ if (! (errtd->ctrl_status & (1 << 23)))
+ {
+ grub_dprintf ("uhci", ">>t status=0x%02x\n", errtd->ctrl_status);
+
+ /* Check if the endpoint is stalled. */
+ if (errtd->ctrl_status & (1 << 22))
+ err = GRUB_USB_ERR_STALL;
+
+ /* Check if an error related to the data buffer occured. */
+ if (errtd->ctrl_status & (1 << 21))
+ err = GRUB_USB_ERR_DATA;
+
+ /* Check if a babble error occured. */
+ if (errtd->ctrl_status & (1 << 20))
+ err = GRUB_USB_ERR_BABBLE;
+
+ /* Check if a NAK occured. */
+ if (errtd->ctrl_status & (1 << 19))
+ err = GRUB_USB_ERR_NAK;
+
+ /* Check if a timeout occured. */
+ if (errtd->ctrl_status & (1 << 18))
+ err = GRUB_USB_ERR_TIMEOUT;
+
+ /* Check if a bitstuff error occured. */
+ if (errtd->ctrl_status & (1 << 17))
+ err = GRUB_USB_ERR_BITSTUFF;
+
+ if (err)
+ goto fail;
+
+ /* Fall through, no errors occured, so the QH might be
+ updated. */
+ grub_dprintf ("uhci", "transaction fallthrough\n");
+ }
+ }
+
+ grub_dprintf ("uhci", "transaction complete\n");
+
+ fail:
+
+ grub_dprintf ("uhci", "transaction failed\n");
+
+ /* Place the QH back in the free list and deallocate the associated
+ TDs. */
+ qh->elinkptr = 1;
+ grub_free_queue (u, td_first);
+
+ return err;
+}
+
+static int
+grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+ struct grub_uhci *u;
+ struct grub_usb_controller dev;
+
+ for (u = uhci; u; u = u->next)
+ {
+ dev.data = u;
+ if (hook (&dev))
+ return 1;
+ }
+
+ return 0;
+}
+
+static grub_err_t
+grub_uhci_portstatus (grub_usb_controller_t dev,
+ unsigned int port, unsigned int enable)
+{
+ struct grub_uhci *u = (struct grub_uhci *) dev->data;
+ int reg;
+ unsigned int status;
+
+ grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port);
+
+ if (port == 0)
+ reg = GRUB_UHCI_REG_PORTSC1;
+ else if (port == 1)
+ reg = GRUB_UHCI_REG_PORTSC2;
+ else
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ "UHCI Root Hub port does not exist");
+
+ status = grub_uhci_readreg16 (u, reg);
+ grub_dprintf ("uhci", "detect=0x%02x\n", status);
+
+ /* Reset the port. */
+ grub_uhci_writereg16 (u, reg, enable << 9);
+
+ /* Wait for the reset to complete. XXX: How long exactly? */
+ grub_millisleep (10);
+ status = grub_uhci_readreg16 (u, reg);
+ grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
+ grub_dprintf ("uhci", "reset completed\n");
+
+ /* Enable the port. */
+ grub_uhci_writereg16 (u, reg, enable << 2);
+ grub_millisleep (10);
+
+ grub_dprintf ("uhci", "waiting for the port to be enabled\n");
+
+ while (! (grub_uhci_readreg16 (u, reg) & (1 << 2)));
+
+ status = grub_uhci_readreg16 (u, reg);
+ grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
+
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_usb_speed_t
+grub_uhci_detect_dev (grub_usb_controller_t dev, int port)
+{
+ struct grub_uhci *u = (struct grub_uhci *) dev->data;
+ int reg;
+ unsigned int status;
+
+ if (port == 0)
+ reg = GRUB_UHCI_REG_PORTSC1;
+ else if (port == 1)
+ reg = GRUB_UHCI_REG_PORTSC2;
+ else
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ "UHCI Root Hub port does not exist");
+
+ status = grub_uhci_readreg16 (u, reg);
+
+ grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port);
+
+ if (! (status & 1))
+ return GRUB_USB_SPEED_NONE;
+ else if (status & (1 << 8))
+ return GRUB_USB_SPEED_LOW;
+ else
+ return GRUB_USB_SPEED_FULL;
+}
+
+static int
+grub_uhci_hubports (grub_usb_controller_t dev __attribute__((unused)))
+{
+ /* The root hub has exactly two ports. */
+ return 2;
+}
+
+
+static struct grub_usb_controller_dev usb_controller =
+{
+ .name = "uhci",
+ .iterate = grub_uhci_iterate,
+ .transfer = grub_uhci_transfer,
+ .hubports = grub_uhci_hubports,
+ .portstatus = grub_uhci_portstatus,
+ .detect_dev = grub_uhci_detect_dev
+};
+
+GRUB_MOD_INIT(uhci)
+{
+ grub_uhci_inithw ();
+ grub_usb_controller_dev_register (&usb_controller);
+ grub_dprintf ("uhci", "registed\n");
+}
+
+GRUB_MOD_FINI(uhci)
+{
+ struct grub_uhci *u;
+
+ /* Disable all UHCI controllers. */
+ for (u = uhci; u; u = u->next)
+ grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
+
+ /* Unregister the controller. */
+ grub_usb_controller_dev_unregister (&usb_controller);
+}
Added: trunk/grub2/bus/usb/usb.c
===================================================================
--- trunk/grub2/bus/usb/usb.c (rev 0)
+++ trunk/grub2/bus/usb/usb.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,263 @@
+/* usb.c - Generic USB interfaces. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/misc.h>
+
+static grub_usb_controller_dev_t grub_usb_list;
+
+void
+grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
+{
+ auto int iterate_hook (grub_usb_controller_t dev);
+
+ /* Iterate over all controllers found by the driver. */
+ int iterate_hook (grub_usb_controller_t dev)
+ {
+ dev->dev = usb;
+
+ /* Enable the ports of the USB Root Hub. */
+ grub_usb_root_hub (dev);
+
+ return 0;
+ }
+
+ usb->next = grub_usb_list;
+ grub_usb_list = usb;
+
+ if (usb->iterate)
+ usb->iterate (iterate_hook);
+}
+
+void
+grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
+{
+ grub_usb_controller_dev_t *p, q;
+
+ for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next)
+ if (q == usb)
+ {
+ *p = q->next;
+ break;
+ }
+}
+
+#if 0
+int
+grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+ grub_usb_controller_dev_t p;
+
+ auto int iterate_hook (grub_usb_controller_t dev);
+
+ int iterate_hook (grub_usb_controller_t dev)
+ {
+ dev->dev = p;
+ if (hook (dev))
+ return 1;
+ return 0;
+ }
+
+ /* Iterate over all controller drivers. */
+ for (p = grub_usb_list; p; p = p->next)
+ {
+ /* Iterate over the busses of the controllers. XXX: Actually, a
+ hub driver should do this. */
+ if (p->iterate (iterate_hook))
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+
+grub_usb_err_t
+grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
+{
+ dev->toggle[endpoint] = 0;
+ return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+ | GRUB_USB_REQTYPE_STANDARD
+ | GRUB_USB_REQTYPE_TARGET_ENDP),
+ GRUB_USB_REQ_CLEAR_FEATURE,
+ GRUB_USB_FEATURE_ENDP_HALT,
+ endpoint, 0, 0);
+}
+
+grub_usb_err_t
+grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ dev->toggle[i] = 0;
+
+ return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+ | GRUB_USB_REQTYPE_STANDARD
+ | GRUB_USB_REQTYPE_TARGET_DEV),
+ GRUB_USB_REQ_SET_CONFIGURATION, configuration,
+ 0, 0, NULL);
+}
+
+grub_usb_err_t
+grub_usb_get_descriptor (grub_usb_device_t dev,
+ grub_uint8_t type, grub_uint8_t index,
+ grub_size_t size, char *data)
+{
+ return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+ | GRUB_USB_REQTYPE_STANDARD
+ | GRUB_USB_REQTYPE_TARGET_DEV),
+ GRUB_USB_REQ_GET_DESCRIPTOR,
+ (type << 8) | index,
+ 0, size, data);
+}
+
+struct grub_usb_desc_endp *
+grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr)
+{
+ int i;
+
+ for (i = 0; i < usbdev->config[0].descconf->numif; i++)
+ {
+ struct grub_usb_desc_if *interf;
+ int j;
+
+ interf = usbdev->config[0].interf[i].descif;
+
+ for (j = 0; j < interf->endpointcnt; j++)
+ {
+ struct grub_usb_desc_endp *endp;
+ endp = &usbdev->config[0].interf[i].descendp[j];
+
+ if (endp->endp_addr == addr)
+ return endp;
+ }
+ }
+
+ return NULL;
+}
+
+grub_usb_err_t
+grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
+ char **string)
+{
+ struct grub_usb_desc_str descstr;
+ struct grub_usb_desc_str *descstrp;
+ grub_usb_err_t err;
+
+ /* Only get the length. */
+ err = grub_usb_control_msg (dev, 1 << 7,
+ 0x06, (3 << 8) | index,
+ langid, 1, (char *) &descstr);
+ if (err)
+ return err;
+
+ descstrp = grub_malloc (descstr.length);
+ if (! descstrp)
+ return GRUB_USB_ERR_INTERNAL;
+ err = grub_usb_control_msg (dev, 1 << 7,
+ 0x06, (3 << 8) | index,
+ langid, descstr.length, (char *) descstrp);
+
+ *string = grub_malloc (descstr.length / 2);
+ if (! *string)
+ {
+ grub_free (descstrp);
+ return GRUB_USB_ERR_INTERNAL;
+ }
+
+ grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str,
descstrp->length / 2 - 1);
+ (*string)[descstr.length / 2 - 1] = '\0';
+ grub_free (descstrp);
+
+ return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_device_initialize (grub_usb_device_t dev)
+{
+ struct grub_usb_desc_device *descdev;
+ struct grub_usb_desc_config config;
+ grub_usb_err_t err;
+ int i;
+
+ err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
+ 0, sizeof (struct grub_usb_desc_device),
+ (char *) &dev->descdev);
+ if (err)
+ return err;
+ descdev = &dev->descdev;
+
+ for (i = 0; i < 8; i++)
+ dev->config[i].descconf = NULL;
+
+ for (i = 0; i < descdev->configcnt; i++)
+ {
+ int pos;
+ int currif;
+ char *data;
+
+ /* First just read the first 4 bytes of the configuration
+ descriptor, after that it is known how many bytes really have
+ to be read. */
+ err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, 4,
+ (char *) &config);
+
+ data = grub_malloc (config.totallen);
+ if (! data)
+ {
+ err = GRUB_USB_ERR_INTERNAL;
+ goto fail;
+ }
+
+ dev->config[i].descconf = (struct grub_usb_desc_config *) data;
+ err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i,
+ config.totallen, data);
+ if (err)
+ goto fail;
+
+ /* Skip the configuration descriptor. */
+ pos = sizeof (struct grub_usb_desc_config);
+
+ /* Read all interfaces. */
+ for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
+ {
+ dev->config[i].interf[currif].descif
+ = (struct grub_usb_desc_if *) &data[pos];
+ pos += sizeof (struct grub_usb_desc_if);
+
+ /* Point to the first endpoint. */
+ dev->config[i].interf[currif].descendp
+ = (struct grub_usb_desc_endp *) &data[pos];
+ pos += (sizeof (struct grub_usb_desc_endp)
+ * dev->config[i].interf[currif].descif->endpointcnt);
+ }
+ }
+
+ return GRUB_USB_ERR_NONE;
+
+ fail:
+
+ for (i = 0; i < 8; i++)
+ grub_free (dev->config[i].descconf);
+
+ return err;
+}
Added: trunk/grub2/bus/usb/usbhub.c
===================================================================
--- trunk/grub2/bus/usb/usbhub.c (rev 0)
+++ trunk/grub2/bus/usb/usbhub.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,193 @@
+/* usb.c - USB Hub Support. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/misc.h>
+
+/* USB Supports 127 devices, with device 0 as special case. */
+static struct grub_usb_device *grub_usb_devs[128];
+
+/* Add a device that currently has device number 0 and resides on
+ CONTROLLER, the Hub reported that the device speed is SPEED. */
+static grub_usb_device_t
+grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed)
+{
+ grub_usb_device_t dev;
+ int i;
+
+ dev = grub_malloc (sizeof (struct grub_usb_device));
+ if (! dev)
+ return NULL;
+
+ dev->controller = *controller;
+ dev->addr = 0;
+ dev->initialized = 0;
+ dev->speed = speed;
+
+ grub_usb_device_initialize (dev);
+
+ /* Assign a new address to the device. */
+ for (i = 1; i < 128; i++)
+ {
+ if (! grub_usb_devs[i])
+ break;
+ }
+ if (grub_usb_devs[i])
+ {
+ grub_error (GRUB_ERR_IO, "Can't assign address to USB device");
+ return NULL;
+ }
+
+ grub_usb_control_msg (dev,
+ (GRUB_USB_REQTYPE_OUT
+ | GRUB_USB_REQTYPE_STANDARD
+ | GRUB_USB_REQTYPE_TARGET_DEV),
+ GRUB_USB_REQ_SET_ADDRESS,
+ i, 0, 0, NULL);
+ dev->addr = i;
+ dev->initialized = 1;
+ grub_usb_devs[i] = dev;
+
+ return dev;
+}
+
+
+static grub_err_t
+grub_usb_add_hub (grub_usb_device_t dev)
+{
+ struct grub_usb_usb_hubdesc hubdesc;
+ grub_err_t err;
+ int i;
+
+ grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+ | GRUB_USB_REQTYPE_CLASS
+ | GRUB_USB_REQTYPE_TARGET_DEV),
+ GRUB_USB_REQ_GET_DESCRIPTOR,
+ (GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
+ 0, sizeof (hubdesc), (char *) &hubdesc);
+
+ /* Iterate over the Hub ports. */
+ for (i = 1; i <= hubdesc.portcnt; i++)
+ {
+ grub_uint32_t status;
+
+ /* Get the port status. */
+ err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+ | GRUB_USB_REQTYPE_CLASS
+ | GRUB_USB_REQTYPE_TARGET_OTHER),
+ GRUB_USB_REQ_HUB_GET_PORT_STATUS,
+ 0, i, sizeof (status), (char *) &status);
+
+ /* Just ignore the device if the Hub does not report the
+ status. */
+ if (err)
+ continue;
+
+ /* If connected, reset and enable the port. */
+ if (status & GRUB_USB_HUB_STATUS_CONNECTED)
+ {
+ grub_usb_speed_t speed;
+
+ /* Determine the device speed. */
+ if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
+ speed = GRUB_USB_SPEED_LOW;
+ else
+ {
+ if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
+ speed = GRUB_USB_SPEED_HIGH;
+ else
+ speed = GRUB_USB_SPEED_FULL;
+ }
+
+ /* A device is actually connected to this port, not enable
+ the port. XXX: Why 0x03? According to some docs it
+ should be 0x0. Check the specification! */
+ err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+ | GRUB_USB_REQTYPE_CLASS
+ | GRUB_USB_REQTYPE_TARGET_OTHER),
+ 0x3, 0x4, i, 0, 0);
+
+ /* If the Hub does not cooperate for this port, just skip
+ the port. */
+ if (err)
+ continue;
+
+ /* Add the device and assign a device address to it. */
+ grub_usb_hub_add_dev (&dev->controller, speed);
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller)
+{
+ grub_err_t err;
+ int ports;
+ int i;
+
+ /* Query the number of ports the root Hub has. */
+ ports = controller->dev->hubports (controller);
+
+ for (i = 0; i < ports; i++)
+ {
+ grub_usb_speed_t speed = controller->dev->detect_dev (controller, i);
+
+ if (speed != GRUB_USB_SPEED_NONE)
+ {
+ grub_usb_device_t dev;
+
+ /* Enable the port. */
+ err = controller->dev->portstatus (controller, i, 1);
+ if (err)
+ continue;
+
+ /* Enable the port and create a device. */
+ dev = grub_usb_hub_add_dev (controller, speed);
+ if (! dev)
+ continue;
+
+ /* If the device is a Hub, scan it for more devices. */
+ if (dev->descdev.class == 0x09)
+ grub_usb_add_hub (dev);
+ }
+ }
+
+ return GRUB_USB_ERR_NONE;
+}
+
+int
+grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
+{
+ int i;
+
+ for (i = 0; i < 128; i++)
+ {
+ if (grub_usb_devs[i])
+ {
+ if (hook (grub_usb_devs[i]))
+ return 1;
+ }
+ }
+
+ return 0;
+}
Added: trunk/grub2/bus/usb/usbtrans.c
===================================================================
--- trunk/grub2/bus/usb/usbtrans.c (rev 0)
+++ trunk/grub2/bus/usb/usbtrans.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,212 @@
+/* usbtrans.c - USB Transfers and Transactions. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+
+grub_usb_err_t
+grub_usb_control_msg (grub_usb_device_t dev,
+ grub_uint8_t reqtype,
+ grub_uint8_t request,
+ grub_uint16_t value,
+ grub_uint16_t index,
+ grub_size_t size, char *data)
+{
+ int i;
+ grub_usb_transfer_t transfer;
+ int datablocks;
+ struct grub_usb_packet_setup setupdata;
+ grub_usb_err_t err;
+ int max;
+
+ grub_dprintf ("usb",
+ "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x
size=%d\n",
+ reqtype, request, value, index, size);
+
+ /* Create a transfer. */
+ transfer = grub_malloc (sizeof (struct grub_usb_transfer));
+ if (! transfer)
+ return grub_errno;
+
+ /* Determine the maximum packet size. */
+ if (dev->initialized)
+ max = dev->descdev.maxsize0;
+ else
+ max = 64;
+
+ datablocks = (size + max - 1) / max;
+
+ /* XXX: Discriminate between different types of control
+ messages. */
+ transfer->transcnt = datablocks + 2;
+ transfer->size = size; /* XXX ? */
+ transfer->endpoint = 0;
+ transfer->devaddr = dev->addr;
+ transfer->type = GRUB_USB_TRANSACTION_TYPE_CONTROL;
+ transfer->max = max;
+ transfer->dev = dev;
+
+ /* Allocate an array of transfer data structures. */
+ transfer->transactions = grub_malloc (transfer->transcnt
+ * sizeof (struct grub_usb_transfer));
+ if (! transfer->transactions)
+ {
+ grub_free (transfer);
+ return grub_errno;
+ }
+
+ /* Build a Setup packet. XXX: Endianess. */
+ setupdata.reqtype = reqtype;
+ setupdata.request = request;
+ setupdata.value = value;
+ setupdata.index = index;
+ setupdata.length = size;
+ transfer->transactions[0].size = sizeof (setupdata);
+ transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
+ transfer->transactions[0].data = (char *) &setupdata;
+ transfer->transactions[0].toggle = 0;
+
+ /* Now the data... XXX: Is this the right way to transfer control
+ transfers? */
+ for (i = 0; i < datablocks; i++)
+ {
+ grub_usb_transaction_t tr = &transfer->transactions[i + 1];
+
+ tr->size = (size > max) ? max : size;
+ /* Use the right most bit as the data toggle. Simple and
+ effective. */
+ tr->toggle = !(i & 1);
+ if (reqtype & 128)
+ tr->pid = GRUB_USB_TRANSFER_TYPE_IN;
+ else
+ tr->pid = GRUB_USB_TRANSFER_TYPE_OUT;
+ tr->data = &data[i * max];
+ size -= max;
+ }
+
+ /* End with an empty OUT transaction. */
+ transfer->transactions[datablocks + 1].size = 0;
+ transfer->transactions[datablocks + 1].data = NULL;
+ if (reqtype & 128)
+ transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT;
+ else
+ transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN;
+
+ transfer->transactions[datablocks + 1].toggle = 1;
+
+ err = dev->controller.dev->transfer (&dev->controller, transfer);
+
+ grub_free (transfer->transactions);
+ grub_free (transfer);
+
+ return err;
+}
+
+static grub_usb_err_t
+grub_usb_bulk_readwrite (grub_usb_device_t dev,
+ int endpoint, grub_size_t size, char *data,
+ grub_transfer_type_t type)
+{
+ int i;
+ grub_usb_transfer_t transfer;
+ int datablocks;
+ unsigned int max;
+ grub_usb_err_t err;
+ int toggle = dev->toggle[endpoint];
+
+ /* Use the maximum packet size given in the endpoint descriptor. */
+ if (dev->initialized)
+ {
+ struct grub_usb_desc_endp *endpdesc;
+ endpdesc = grub_usb_get_endpdescriptor (dev, 0);
+
+ if (endpdesc)
+ max = endpdesc->maxpacket;
+ else
+ max = 64;
+ }
+ else
+ max = 64;
+
+ /* Create a transfer. */
+ transfer = grub_malloc (sizeof (struct grub_usb_transfer));
+ if (! transfer)
+ return grub_errno;
+
+ datablocks = ((size + max - 1) / max);
+ transfer->transcnt = datablocks;
+ transfer->size = size - 1;
+ transfer->endpoint = endpoint;
+ transfer->devaddr = dev->addr;
+ transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
+ transfer->max = max;
+ transfer->dev = dev;
+
+ /* Allocate an array of transfer data structures. */
+ transfer->transactions = grub_malloc (transfer->transcnt
+ * sizeof (struct grub_usb_transfer));
+ if (! transfer->transactions)
+ {
+ grub_free (transfer);
+ return grub_errno;
+ }
+
+ /* Set up all transfers. */
+ for (i = 0; i < datablocks; i++)
+ {
+ grub_usb_transaction_t tr = &transfer->transactions[i];
+
+ tr->size = (size > max) ? max : size;
+ /* XXX: Use the right most bit as the data toggle. Simple and
+ effective. */
+ tr->toggle = toggle;
+ toggle = toggle ? 0 : 1;
+ tr->pid = type;
+ tr->data = &data[i * max];
+ size -= tr->size;
+ }
+
+ err = dev->controller.dev->transfer (&dev->controller, transfer);
+ grub_dprintf ("usb", "toggle=%d\n", toggle);
+ dev->toggle[endpoint] = toggle;
+
+ grub_free (transfer->transactions);
+ grub_free (transfer);
+
+ return err;
+}
+
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+ int endpoint, grub_size_t size, char *data)
+{
+ return grub_usb_bulk_readwrite (dev, endpoint, size, data,
+ GRUB_USB_TRANSFER_TYPE_OUT);
+}
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+ int endpoint, grub_size_t size, char *data)
+{
+ return grub_usb_bulk_readwrite (dev, endpoint, size, data,
+ GRUB_USB_TRANSFER_TYPE_IN);
+}
Added: trunk/grub2/commands/usbtest.c
===================================================================
--- trunk/grub2/commands/usbtest.c (rev 0)
+++ trunk/grub2/commands/usbtest.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,160 @@
+/* usbtest.c - test module for USB */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/usb.h>
+
+static const char *usb_classes[] =
+ {
+ "",
+ "Audio",
+ "Communication Interface",
+ "HID",
+ "",
+ "Physical",
+ "Image",
+ "Printer",
+ "Mass Storage",
+ "Hub",
+ "Data Interface",
+ "Smart Card",
+ "Content Security",
+ "Video"
+ };
+
+static const char *usb_endp_type[] =
+ {
+ "Control",
+ "Isochronous",
+ "Bulk",
+ "Interrupt"
+ };
+
+static const char *usb_devspeed[] =
+ {
+ "",
+ "Low",
+ "Full",
+ "High"
+ };
+
+static void
+usb_print_str (const char *description, grub_usb_device_t dev, int idx)
+{
+ char *name;
+ /* XXX: LANGID */
+
+ if (! idx)
+ return;
+
+ grub_usb_get_string (dev, idx, 0x0409, &name);
+ grub_printf ("%s: `%s'\n", description, name);
+ grub_free (name);
+}
+
+static int
+usb_iterate (grub_usb_device_t dev)
+{
+ struct grub_usb_desc_device *descdev;
+ int i;
+
+ descdev = &dev->descdev;
+
+ usb_print_str ("Product", dev, descdev->strprod);
+ usb_print_str ("Vendor", dev, descdev->strvendor);
+ usb_print_str ("Serial", dev, descdev->strserial);
+
+ if (descdev->class > 0 && descdev->class <= 0x0E)
+ grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
+ descdev->class, usb_classes[descdev->class],
+ descdev->subclass, descdev->protocol);
+ grub_printf ("USB version %d.%d, VendorID: 0x%02x, ProductID: 0x%02x, #conf:
%d\n",
+ descdev->usbrel >> 8, (descdev->usbrel >> 4) & 0x0F,
+ descdev->vendorid, descdev->prodid, descdev->configcnt);
+
+ grub_printf ("%s speed device\n", usb_devspeed[dev->speed]);
+
+ for (i = 0; i < descdev->configcnt; i++)
+ {
+ struct grub_usb_desc_config *config;
+
+ config = dev->config[i].descconf;
+ usb_print_str ("Configuration:", dev, config->strconfig);
+ }
+
+ for (i = 0; i < dev->config[0].descconf->numif; i++)
+ {
+ int j;
+ struct grub_usb_desc_if *interf;
+ interf = dev->config[0].interf[i].descif;
+
+ grub_printf ("Interface #%d: #Endpoints: %d ",
+ i, interf->endpointcnt);
+ if (interf->class > 0 && interf->class <= 0x0E)
+ grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
+ interf->class, usb_classes[interf->class],
+ interf->subclass, interf->protocol);
+
+ usb_print_str ("Interface", dev, interf->strif);
+
+ for (j = 0; j < interf->endpointcnt; j++)
+ {
+ struct grub_usb_desc_endp *endp;
+ endp = &dev->config[0].interf[i].descendp[j];
+
+ grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type:
%s, latency: %d\n",
+ endp->endp_addr & 15,
+ (endp->endp_addr & 128) ? "IN" : "OUT",
+ endp->maxpacket, usb_endp_type[endp->attrib & 3],
+ endp->interval);
+ }
+ }
+
+ grub_printf("\n");
+
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_usbtest (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ grub_printf ("USB devices:\n\n");
+ grub_usb_iterate (usb_iterate);
+
+ return 0;
+}
+
+GRUB_MOD_INIT(usbtest)
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("usb", grub_cmd_usbtest, GRUB_COMMAND_FLAG_BOTH,
+ "usb", "Test USB support", 0);
+}
+
+GRUB_MOD_FINI(usbtest)
+{
+ grub_unregister_command ("usb");
+}
Modified: trunk/grub2/conf/i386-pc.mk
===================================================================
--- trunk/grub2/conf/i386-pc.mk 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/conf/i386-pc.mk 2009-02-08 17:58:32 UTC (rev 1982)
@@ -525,7 +525,7 @@
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \
commands/i386/cpuid.c \
- disk/host.c disk/loopback.c \
+ disk/host.c disk/loopback.c disk/scsi.c \
fs/fshelp.c \
\
io/gzio.c \
@@ -553,11 +553,11 @@
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
grub_emu_init.c
-CLEANFILES += grub-emu$(EXEEXT) grub_emu-commands_boot.o
grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o
grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o
grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o
grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o
grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o
grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o
grub_emu-disk_loopback.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o
grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o
grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o
grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o
grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o
grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o
grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o
grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o
grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o
grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o
grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o
grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o
grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o
grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o
grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o
grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o
grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o
grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o
grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o
grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o
grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o
-MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d
grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d
grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d
grub_emu-commands_test.d grub_emu-commands_search.d
grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d
grub_emu-lib_hexdump.d grub_emu-commands_i386_pc_halt.d
grub_emu-commands_reboot.d grub_emu-commands_i386_cpuid.d grub_emu-disk_host.d
grub_emu-disk_loopback.d grub_emu-fs_fshelp.d grub_emu-io_gzio.d
grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d
grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d
grub_emu-normal_execute.d grub_emu-kern_file.d grub_emu-kern_fs.d
grub_emu-normal_lexer.d grub_emu-kern_loader.d grub_emu-kern_main.d
grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-grub_script_tab.d
grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d
grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d
grub_emu-normal_function.d grub_emu-normal_completion.d grub_emu-normal_main.d
grub_emu-normal_color.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d
grub_emu-normal_menu_viewer.d grub_emu-normal_misc.d grub_emu-normal_script.d
grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d
grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d
grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_ext2.d grub_emu-fs_fat.d
grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d
grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d
grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d
grub_emu-fs_afs.d grub_emu-fs_tar.d grub_emu-util_console.d
grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d
grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-util_i386_pc_misc.d
grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d
grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d
grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-grub_emu_init.d
+CLEANFILES += grub-emu$(EXEEXT) grub_emu-commands_boot.o
grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o
grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o
grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o
grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o
grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o
grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o
grub_emu-disk_loopback.o grub_emu-disk_scsi.o grub_emu-fs_fshelp.o
grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o
grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o
grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o
grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o
grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o
grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o
grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o
grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o
grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o
grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o
grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o
grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o
grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o
grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o
grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o
grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o
grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o
grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o
grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o
grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o
+MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d
grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d
grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d
grub_emu-commands_test.d grub_emu-commands_search.d
grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d
grub_emu-lib_hexdump.d grub_emu-commands_i386_pc_halt.d
grub_emu-commands_reboot.d grub_emu-commands_i386_cpuid.d grub_emu-disk_host.d
grub_emu-disk_loopback.d grub_emu-disk_scsi.d grub_emu-fs_fshelp.d
grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d
grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d
grub_emu-normal_execute.d grub_emu-kern_file.d grub_emu-kern_fs.d
grub_emu-normal_lexer.d grub_emu-kern_loader.d grub_emu-kern_main.d
grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-grub_script_tab.d
grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d
grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d
grub_emu-normal_function.d grub_emu-normal_completion.d grub_emu-normal_main.d
grub_emu-normal_color.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d
grub_emu-normal_menu_viewer.d grub_emu-normal_misc.d grub_emu-normal_script.d
grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d
grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d
grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_ext2.d grub_emu-fs_fat.d
grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d
grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d
grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d
grub_emu-fs_afs.d grub_emu-fs_tar.d grub_emu-util_console.d
grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d
grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-util_i386_pc_misc.d
grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d
grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d
grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-grub_emu_init.d
-grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o
grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o
grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o
grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o
grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o
grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o
grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o
grub_emu-disk_loopback.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o
grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o
grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o
grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o
grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o
grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o
grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o
grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o
grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o
grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o
grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o
grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o
grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o
grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o
grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o
grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o
grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o
grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o
grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o
grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o
grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o
- $(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o
grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o
grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o
grub_emu-commands_test.o grub_emu-commands_search.o
grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o
grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o
grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o
grub_emu-disk_loopback.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o
grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o
grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o
grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o
grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o
grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o
grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o
grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o
grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o
grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o
grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o
grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o
grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o
grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o
grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o
grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o
grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o
grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o
grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o
grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o
grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o
$(LDFLAGS) $(grub_emu_LDFLAGS)
+grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o
grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o
grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o
grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o
grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o
grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o
grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o
grub_emu-disk_loopback.o grub_emu-disk_scsi.o grub_emu-fs_fshelp.o
grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o
grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o
grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o
grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o
grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o
grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o
grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o
grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o
grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o
grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o
grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o
grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o
grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o
grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o
grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o
grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o
grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o
grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o
grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o
grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o
+ $(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o
grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o
grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o
grub_emu-commands_test.o grub_emu-commands_search.o
grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o
grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o
grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o
grub_emu-disk_loopback.o grub_emu-disk_scsi.o grub_emu-fs_fshelp.o
grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o
grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o
grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o
grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o
grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o
grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o
grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o
grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o
grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o
grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o
grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o
grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o
grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o
grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o
grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o
grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o
grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o
grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o
grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o
grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o
$(LDFLAGS) $(grub_emu_LDFLAGS)
grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS)
-DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
@@ -631,6 +631,10 @@
$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1
$(grub_emu_CFLAGS) -MD -c -o $@ $<
-include grub_emu-disk_loopback.d
+grub_emu-disk_scsi.o: disk/scsi.c $(disk/scsi.c_DEPENDENCIES)
+ $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1
$(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_scsi.d
+
grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1
$(grub_emu_CFLAGS) -MD -c -o $@ $<
-include grub_emu-fs_fshelp.d
@@ -912,8 +916,36 @@
-include grub_emu-grub_emu_init.d
-grub_emu_LDFLAGS = $(LIBCURSES)
+grub_emu_LDFLAGS = $(LIBCURSES)
+ifeq ($(enable_grub_emu_usb), yes)
+grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \
+ commands/usbtest.c
+CLEANFILES += grub-emu$(EXEEXT) grub_emu-disk_usbms.o grub_emu-util_usb.o
grub_emu-bus_usb_usb.o grub_emu-commands_usbtest.o
+MOSTLYCLEANFILES += grub_emu-disk_usbms.d grub_emu-util_usb.d
grub_emu-bus_usb_usb.d grub_emu-commands_usbtest.d
+
+grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-disk_usbms.o grub_emu-util_usb.o
grub_emu-bus_usb_usb.o grub_emu-commands_usbtest.o
+ $(CC) -o $@ grub_emu-disk_usbms.o grub_emu-util_usb.o
grub_emu-bus_usb_usb.o grub_emu-commands_usbtest.o $(LDFLAGS)
$(grub_emu_LDFLAGS)
+
+grub_emu-disk_usbms.o: disk/usbms.c $(disk/usbms.c_DEPENDENCIES)
+ $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1
$(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_usbms.d
+
+grub_emu-util_usb.o: util/usb.c $(util/usb.c_DEPENDENCIES)
+ $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1
$(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_usb.d
+
+grub_emu-bus_usb_usb.o: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES)
+ $(CC) -Ibus/usb -I$(srcdir)/bus/usb $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1
$(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-bus_usb_usb.d
+
+grub_emu-commands_usbtest.o: commands/usbtest.c
$(commands/usbtest.c_DEPENDENCIES)
+ $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS)
-DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_usbtest.d
+
+grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB)
+endif
+
# Scripts.
sbin_SCRIPTS = grub-install
bin_SCRIPTS = grub-mkrescue
@@ -942,7 +974,8 @@
vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \
ata.mod vga.mod memdisk.mod pci.mod lspci.mod \
aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
- datehook.mod lsmmap.mod
+ datehook.mod lsmmap.mod \
+ usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod
# For biosdisk.mod.
biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
@@ -2673,6 +2706,329 @@
bsd_mod_CFLAGS = $(COMMON_CFLAGS)
bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For usb.mod
+usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
+CLEANFILES += usb.mod mod-usb.o mod-usb.c pre-usb.o usb_mod-bus_usb_usb.o
usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o und-usb.lst
+ifneq ($(usb_mod_EXPORTS),no)
+CLEANFILES += def-usb.lst
+DEFSYMFILES += def-usb.lst
+endif
+MOSTLYCLEANFILES += usb_mod-bus_usb_usb.d usb_mod-bus_usb_usbtrans.d
usb_mod-bus_usb_usbhub.d
+UNDSYMFILES += und-usb.lst
+
+usb.mod: pre-usb.o mod-usb.o $(TARGET_OBJ2ELF)
+ -rm -f $@
+ $(TARGET_CC) $(usb_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS)
-Wl,-r,-d -o $@ pre-usb.o mod-usb.o
+ if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f
$@; exit 1); fi
+ $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K
_grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+
+pre-usb.o: $(usb_mod_DEPENDENCIES) usb_mod-bus_usb_usb.o
usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o
+ -rm -f $@
+ $(TARGET_CC) $(usb_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
usb_mod-bus_usb_usb.o usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o
+
+mod-usb.o: mod-usb.c
+ $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -c
-o $@ $<
+
+mod-usb.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+ sh $(srcdir)/genmodsrc.sh 'usb' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(usb_mod_EXPORTS),no)
+def-usb.lst: pre-usb.o
+ $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usb/' > $@
+endif
+
+und-usb.lst: pre-usb.o
+ echo 'usb' > $@
+ $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+usb_mod-bus_usb_usb.o: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES)
+ $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $<
+-include usb_mod-bus_usb_usb.d
+
+CLEANFILES += cmd-usb_mod-bus_usb_usb.lst fs-usb_mod-bus_usb_usb.lst
partmap-usb_mod-bus_usb_usb.lst
+COMMANDFILES += cmd-usb_mod-bus_usb_usb.lst
+FSFILES += fs-usb_mod-bus_usb_usb.lst
+PARTMAPFILES += partmap-usb_mod-bus_usb_usb.lst
+
+cmd-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES)
gencmdlist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1)
+
+fs-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES)
genfslist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1)
+
+partmap-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES)
genpartmaplist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1)
+
+
+usb_mod-bus_usb_usbtrans.o: bus/usb/usbtrans.c
$(bus/usb/usbtrans.c_DEPENDENCIES)
+ $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $<
+-include usb_mod-bus_usb_usbtrans.d
+
+CLEANFILES += cmd-usb_mod-bus_usb_usbtrans.lst fs-usb_mod-bus_usb_usbtrans.lst
partmap-usb_mod-bus_usb_usbtrans.lst
+COMMANDFILES += cmd-usb_mod-bus_usb_usbtrans.lst
+FSFILES += fs-usb_mod-bus_usb_usbtrans.lst
+PARTMAPFILES += partmap-usb_mod-bus_usb_usbtrans.lst
+
+cmd-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c
$(bus/usb/usbtrans.c_DEPENDENCIES) gencmdlist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1)
+
+fs-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c
$(bus/usb/usbtrans.c_DEPENDENCIES) genfslist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1)
+
+partmap-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c
$(bus/usb/usbtrans.c_DEPENDENCIES) genpartmaplist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1)
+
+
+usb_mod-bus_usb_usbhub.o: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES)
+ $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $<
+-include usb_mod-bus_usb_usbhub.d
+
+CLEANFILES += cmd-usb_mod-bus_usb_usbhub.lst fs-usb_mod-bus_usb_usbhub.lst
partmap-usb_mod-bus_usb_usbhub.lst
+COMMANDFILES += cmd-usb_mod-bus_usb_usbhub.lst
+FSFILES += fs-usb_mod-bus_usb_usbhub.lst
+PARTMAPFILES += partmap-usb_mod-bus_usb_usbhub.lst
+
+cmd-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c
$(bus/usb/usbhub.c_DEPENDENCIES) gencmdlist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1)
+
+fs-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c
$(bus/usb/usbhub.c_DEPENDENCIES) genfslist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1)
+
+partmap-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c
$(bus/usb/usbhub.c_DEPENDENCIES) genpartmaplist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1)
+
+
+usb_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbtest.mod
+usbtest_mod_SOURCES = commands/usbtest.c
+CLEANFILES += usbtest.mod mod-usbtest.o mod-usbtest.c pre-usbtest.o
usbtest_mod-commands_usbtest.o und-usbtest.lst
+ifneq ($(usbtest_mod_EXPORTS),no)
+CLEANFILES += def-usbtest.lst
+DEFSYMFILES += def-usbtest.lst
+endif
+MOSTLYCLEANFILES += usbtest_mod-commands_usbtest.d
+UNDSYMFILES += und-usbtest.lst
+
+usbtest.mod: pre-usbtest.o mod-usbtest.o $(TARGET_OBJ2ELF)
+ -rm -f $@
+ $(TARGET_CC) $(usbtest_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS)
-Wl,-r,-d -o $@ pre-usbtest.o mod-usbtest.o
+ if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f
$@; exit 1); fi
+ $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K
_grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+
+pre-usbtest.o: $(usbtest_mod_DEPENDENCIES) usbtest_mod-commands_usbtest.o
+ -rm -f $@
+ $(TARGET_CC) $(usbtest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
usbtest_mod-commands_usbtest.o
+
+mod-usbtest.o: mod-usbtest.c
+ $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS)
-c -o $@ $<
+
+mod-usbtest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+ sh $(srcdir)/genmodsrc.sh 'usbtest' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(usbtest_mod_EXPORTS),no)
+def-usbtest.lst: pre-usbtest.o
+ $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usbtest/' > $@
+endif
+
+und-usbtest.lst: pre-usbtest.o
+ echo 'usbtest' > $@
+ $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+usbtest_mod-commands_usbtest.o: commands/usbtest.c
$(commands/usbtest.c_DEPENDENCIES)
+ $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -MD -c -o $@ $<
+-include usbtest_mod-commands_usbtest.d
+
+CLEANFILES += cmd-usbtest_mod-commands_usbtest.lst
fs-usbtest_mod-commands_usbtest.lst partmap-usbtest_mod-commands_usbtest.lst
+COMMANDFILES += cmd-usbtest_mod-commands_usbtest.lst
+FSFILES += fs-usbtest_mod-commands_usbtest.lst
+PARTMAPFILES += partmap-usbtest_mod-commands_usbtest.lst
+
+cmd-usbtest_mod-commands_usbtest.lst: commands/usbtest.c
$(commands/usbtest.c_DEPENDENCIES) gencmdlist.sh
+ set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh usbtest > $@ || (rm -f $@; exit 1)
+
+fs-usbtest_mod-commands_usbtest.lst: commands/usbtest.c
$(commands/usbtest.c_DEPENDENCIES) genfslist.sh
+ set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh usbtest > $@ || (rm -f $@; exit 1)
+
+partmap-usbtest_mod-commands_usbtest.lst: commands/usbtest.c
$(commands/usbtest.c_DEPENDENCIES) genpartmaplist.sh
+ set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh usbtest > $@ || (rm -f $@; exit 1)
+
+
+usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
+usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For uhci.mod
+uhci_mod_SOURCES = bus/usb/uhci.c
+CLEANFILES += uhci.mod mod-uhci.o mod-uhci.c pre-uhci.o
uhci_mod-bus_usb_uhci.o und-uhci.lst
+ifneq ($(uhci_mod_EXPORTS),no)
+CLEANFILES += def-uhci.lst
+DEFSYMFILES += def-uhci.lst
+endif
+MOSTLYCLEANFILES += uhci_mod-bus_usb_uhci.d
+UNDSYMFILES += und-uhci.lst
+
+uhci.mod: pre-uhci.o mod-uhci.o $(TARGET_OBJ2ELF)
+ -rm -f $@
+ $(TARGET_CC) $(uhci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS)
-Wl,-r,-d -o $@ pre-uhci.o mod-uhci.o
+ if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f
$@; exit 1); fi
+ $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K
_grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+
+pre-uhci.o: $(uhci_mod_DEPENDENCIES) uhci_mod-bus_usb_uhci.o
+ -rm -f $@
+ $(TARGET_CC) $(uhci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
uhci_mod-bus_usb_uhci.o
+
+mod-uhci.o: mod-uhci.c
+ $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -c
-o $@ $<
+
+mod-uhci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+ sh $(srcdir)/genmodsrc.sh 'uhci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(uhci_mod_EXPORTS),no)
+def-uhci.lst: pre-uhci.o
+ $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 uhci/' > $@
+endif
+
+und-uhci.lst: pre-uhci.o
+ echo 'uhci' > $@
+ $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+uhci_mod-bus_usb_uhci.o: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES)
+ $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -MD -c -o $@ $<
+-include uhci_mod-bus_usb_uhci.d
+
+CLEANFILES += cmd-uhci_mod-bus_usb_uhci.lst fs-uhci_mod-bus_usb_uhci.lst
partmap-uhci_mod-bus_usb_uhci.lst
+COMMANDFILES += cmd-uhci_mod-bus_usb_uhci.lst
+FSFILES += fs-uhci_mod-bus_usb_uhci.lst
+PARTMAPFILES += partmap-uhci_mod-bus_usb_uhci.lst
+
+cmd-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES)
gencmdlist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh uhci > $@ || (rm -f $@; exit 1)
+
+fs-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES)
genfslist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh uhci > $@ || (rm -f $@; exit 1)
+
+partmap-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c
$(bus/usb/uhci.c_DEPENDENCIES) genpartmaplist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh uhci > $@ || (rm -f $@; exit 1)
+
+
+uhci_mod_CFLAGS = $(COMMON_CFLAGS)
+uhci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ohci.mod
+ohci_mod_SOURCES = bus/usb/ohci.c
+CLEANFILES += ohci.mod mod-ohci.o mod-ohci.c pre-ohci.o
ohci_mod-bus_usb_ohci.o und-ohci.lst
+ifneq ($(ohci_mod_EXPORTS),no)
+CLEANFILES += def-ohci.lst
+DEFSYMFILES += def-ohci.lst
+endif
+MOSTLYCLEANFILES += ohci_mod-bus_usb_ohci.d
+UNDSYMFILES += und-ohci.lst
+
+ohci.mod: pre-ohci.o mod-ohci.o $(TARGET_OBJ2ELF)
+ -rm -f $@
+ $(TARGET_CC) $(ohci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS)
-Wl,-r,-d -o $@ pre-ohci.o mod-ohci.o
+ if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f
$@; exit 1); fi
+ $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K
_grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+
+pre-ohci.o: $(ohci_mod_DEPENDENCIES) ohci_mod-bus_usb_ohci.o
+ -rm -f $@
+ $(TARGET_CC) $(ohci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
ohci_mod-bus_usb_ohci.o
+
+mod-ohci.o: mod-ohci.c
+ $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -c
-o $@ $<
+
+mod-ohci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+ sh $(srcdir)/genmodsrc.sh 'ohci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ohci_mod_EXPORTS),no)
+def-ohci.lst: pre-ohci.o
+ $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ohci/' > $@
+endif
+
+und-ohci.lst: pre-ohci.o
+ echo 'ohci' > $@
+ $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ohci_mod-bus_usb_ohci.o: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES)
+ $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -MD -c -o $@ $<
+-include ohci_mod-bus_usb_ohci.d
+
+CLEANFILES += cmd-ohci_mod-bus_usb_ohci.lst fs-ohci_mod-bus_usb_ohci.lst
partmap-ohci_mod-bus_usb_ohci.lst
+COMMANDFILES += cmd-ohci_mod-bus_usb_ohci.lst
+FSFILES += fs-ohci_mod-bus_usb_ohci.lst
+PARTMAPFILES += partmap-ohci_mod-bus_usb_ohci.lst
+
+cmd-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES)
gencmdlist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh ohci > $@ || (rm -f $@; exit 1)
+
+fs-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES)
genfslist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh ohci > $@ || (rm -f $@; exit 1)
+
+partmap-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c
$(bus/usb/ohci.c_DEPENDENCIES) genpartmaplist.sh
+ set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh ohci > $@ || (rm -f $@; exit 1)
+
+
+ohci_mod_CFLAGS = $(COMMON_CFLAGS)
+ohci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbms.mod
+usbms_mod_SOURCES = disk/usbms.c
+CLEANFILES += usbms.mod mod-usbms.o mod-usbms.c pre-usbms.o
usbms_mod-disk_usbms.o und-usbms.lst
+ifneq ($(usbms_mod_EXPORTS),no)
+CLEANFILES += def-usbms.lst
+DEFSYMFILES += def-usbms.lst
+endif
+MOSTLYCLEANFILES += usbms_mod-disk_usbms.d
+UNDSYMFILES += und-usbms.lst
+
+usbms.mod: pre-usbms.o mod-usbms.o $(TARGET_OBJ2ELF)
+ -rm -f $@
+ $(TARGET_CC) $(usbms_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS)
-Wl,-r,-d -o $@ pre-usbms.o mod-usbms.o
+ if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f
$@; exit 1); fi
+ $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K
_grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+
+pre-usbms.o: $(usbms_mod_DEPENDENCIES) usbms_mod-disk_usbms.o
+ -rm -f $@
+ $(TARGET_CC) $(usbms_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
usbms_mod-disk_usbms.o
+
+mod-usbms.o: mod-usbms.c
+ $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -c
-o $@ $<
+
+mod-usbms.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+ sh $(srcdir)/genmodsrc.sh 'usbms' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(usbms_mod_EXPORTS),no)
+def-usbms.lst: pre-usbms.o
+ $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usbms/' > $@
+endif
+
+und-usbms.lst: pre-usbms.o
+ echo 'usbms' > $@
+ $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+usbms_mod-disk_usbms.o: disk/usbms.c $(disk/usbms.c_DEPENDENCIES)
+ $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -MD -c -o $@ $<
+-include usbms_mod-disk_usbms.d
+
+CLEANFILES += cmd-usbms_mod-disk_usbms.lst fs-usbms_mod-disk_usbms.lst
partmap-usbms_mod-disk_usbms.lst
+COMMANDFILES += cmd-usbms_mod-disk_usbms.lst
+FSFILES += fs-usbms_mod-disk_usbms.lst
+PARTMAPFILES += partmap-usbms_mod-disk_usbms.lst
+
+cmd-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES)
gencmdlist.sh
+ set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh usbms > $@ || (rm -f $@; exit 1)
+
+fs-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES)
genfslist.sh
+ set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh usbms > $@ || (rm -f $@; exit 1)
+
+partmap-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES)
genpartmaplist.sh
+ set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh usbms > $@ || (rm -f $@; exit 1)
+
+
+usbms_mod_CFLAGS = $(COMMON_CFLAGS)
+usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
# For pxe.mod
pxe_mod_SOURCES = fs/i386/pc/pxe.c
CLEANFILES += pxe.mod mod-pxe.o mod-pxe.c pre-pxe.o pxe_mod-fs_i386_pc_pxe.o
und-pxe.lst
Modified: trunk/grub2/conf/i386-pc.rmk
===================================================================
--- trunk/grub2/conf/i386-pc.rmk 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/conf/i386-pc.rmk 2009-02-08 17:58:32 UTC (rev 1982)
@@ -118,7 +118,7 @@
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \
commands/i386/cpuid.c \
- disk/host.c disk/loopback.c \
+ disk/host.c disk/loopback.c disk/scsi.c \
fs/fshelp.c \
\
io/gzio.c \
@@ -147,8 +147,14 @@
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
grub_emu_init.c
-grub_emu_LDFLAGS = $(LIBCURSES)
+grub_emu_LDFLAGS = $(LIBCURSES)
+ifeq ($(enable_grub_emu_usb), yes)
+grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \
+ commands/usbtest.c
+grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB)
+endif
+
# Scripts.
sbin_SCRIPTS = grub-install
bin_SCRIPTS = grub-mkrescue
@@ -165,7 +171,8 @@
vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \
ata.mod vga.mod memdisk.mod pci.mod lspci.mod \
aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
- datehook.mod lsmmap.mod
+ datehook.mod lsmmap.mod \
+ usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod
# For biosdisk.mod.
biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
@@ -301,6 +308,31 @@
bsd_mod_CFLAGS = $(COMMON_CFLAGS)
bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For usb.mod
+usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
+usb_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbtest.mod
+usbtest_mod_SOURCES = commands/usbtest.c
+usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
+usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For uhci.mod
+uhci_mod_SOURCES = bus/usb/uhci.c
+uhci_mod_CFLAGS = $(COMMON_CFLAGS)
+uhci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ohci.mod
+ohci_mod_SOURCES = bus/usb/ohci.c
+ohci_mod_CFLAGS = $(COMMON_CFLAGS)
+ohci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbms.mod
+usbms_mod_SOURCES = disk/usbms.c
+usbms_mod_CFLAGS = $(COMMON_CFLAGS)
+usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
# For pxe.mod
pxe_mod_SOURCES = fs/i386/pc/pxe.c
pxe_mod_CFLAGS = $(COMMON_CFLAGS)
Modified: trunk/grub2/config.h.in
===================================================================
--- trunk/grub2/config.h.in 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/config.h.in 2009-02-08 17:58:32 UTC (rev 1982)
@@ -76,6 +76,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the <usb.h> header file. */
+#undef HAVE_USB_H
+
/* Define to 1 if you enable memory manager debugging. */
#undef MM_DEBUG
Modified: trunk/grub2/configure
===================================================================
--- trunk/grub2/configure 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/configure 2009-02-08 17:58:32 UTC (rev 1982)
@@ -700,7 +700,9 @@
TARGET_LDFLAGS
MODULE_LDFLAGS
LIBCURSES
+LIBUSB
enable_grub_emu
+enable_grub_emu_usb
enable_grub_fstest
enable_grub_pe2elf
FREETYPE
@@ -1303,6 +1305,8 @@
--enable-lzo use lzo to compress kernel (default is lzma)
--enable-mm-debug include memory manager debugging
--enable-grub-emu build and install the `grub-emu' debugging utility
+ --enable-grub-emu-usb build and install the `grub-emu' debugging utility
+ with USB support
--enable-grub-fstest build and install the `grub-fstest' debugging
utility
--enable-grub-pe2elf build and install the `grub-pe2elf' conversion
@@ -7832,6 +7836,11 @@
enableval=$enable_grub_emu;
fi
+# Check whether --enable-grub-emu-usb was given.
+if test "${enable_grub_emu_usb+set}" = set; then
+ enableval=$enable_grub_emu_usb;
+fi
+
if [ x"$enable_grub_emu" = xyes ]; then
# Check for curses libraries.
{ echo "$as_me:$LINENO: checking for wgetch in -lncurses" >&5
@@ -8413,9 +8422,235 @@
done
+
+ if [ x"$enable_grub_emu_usb" = xyes ]; then
+ # Check for libusb libraries.
+ { echo "$as_me:$LINENO: checking for usb_claim_interface in -lusb" >&5
+echo $ECHO_N "checking for usb_claim_interface in -lusb... $ECHO_C" >&6; }
+if test "${ac_cv_lib_usb_usb_claim_interface+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lusb $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char usb_claim_interface ();
+int
+main ()
+{
+return usb_claim_interface ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_lib_usb_usb_claim_interface=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_usb_usb_claim_interface=no
fi
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_claim_interface" >&5
+echo "${ECHO_T}$ac_cv_lib_usb_usb_claim_interface" >&6; }
+if test $ac_cv_lib_usb_usb_claim_interface = yes; then
+ LIBUSB="-lusb"
+else
+ { { echo "$as_me:$LINENO: error: libusb libraries are required to build
\`grub-emu' with USB support" >&5
+echo "$as_me: error: libusb libraries are required to build \`grub-emu' with
USB support" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+ # Check for headers.
+
+for ac_header in usb.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler,
rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the
preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the
compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be
compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing
prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite
headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf
documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But
Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be
Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the
preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result"
>&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler
will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take
precedence" >&2;}
+ ( cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to address@hidden ##
+## ------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+ { { echo "$as_me:$LINENO: error: libusb header file is required to build
\`grub-emu' with USB support" >&5
+echo "$as_me: error: libusb header file is required to build \`grub-emu' with
USB support" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+done
+
+ fi
+fi
+
+
+
# Check whether --enable-grub-fstest was given.
if test "${enable_grub_fstest+set}" = set; then
enableval=$enable_grub_fstest;
@@ -9209,7 +9444,9 @@
TARGET_LDFLAGS!$TARGET_LDFLAGS$ac_delim
MODULE_LDFLAGS!$MODULE_LDFLAGS$ac_delim
LIBCURSES!$LIBCURSES$ac_delim
+LIBUSB!$LIBUSB$ac_delim
enable_grub_emu!$enable_grub_emu$ac_delim
+enable_grub_emu_usb!$enable_grub_emu_usb$ac_delim
enable_grub_fstest!$enable_grub_fstest$ac_delim
enable_grub_pe2elf!$enable_grub_pe2elf$ac_delim
FREETYPE!$FREETYPE$ac_delim
@@ -9220,7 +9457,7 @@
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 96; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -9239,7 +9476,7 @@
cat >>$CONFIG_STATUS <<_ACEOF
cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
_ACEOF
sed '
s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
@@ -9252,8 +9489,6 @@
' >>$CONFIG_STATUS <conf$$subs.sed
rm -f conf$$subs.sed
cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
CEOF$ac_eof
_ACEOF
@@ -9501,7 +9736,7 @@
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
s&@INSTALL@&$ac_INSTALL&;t t
$ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed 's/|#_!!_#|//g' >$tmp/out
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
Modified: trunk/grub2/configure.ac
===================================================================
--- trunk/grub2/configure.ac 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/configure.ac 2009-02-08 17:58:32 UTC (rev 1982)
@@ -382,6 +382,9 @@
AC_ARG_ENABLE([grub-emu],
[AS_HELP_STRING([--enable-grub-emu],
[build and install the `grub-emu' debugging
utility])])
+AC_ARG_ENABLE([grub-emu-usb],
+ [AS_HELP_STRING([--enable-grub-emu-usb],
+ [build and install the `grub-emu' debugging
utility with USB support])])
[if [ x"$enable_grub_emu" = xyes ]; then
# Check for curses libraries.]
AC_CHECK_LIB([ncurses], [wgetch], [LIBCURSES="-lncurses"],
@@ -394,8 +397,20 @@
[AC_CHECK_HEADERS([ncurses.h], [],
[AC_CHECK_HEADERS([curses.h], [],
[AC_MSG_ERROR([(n)curses header files are required to build
`grub-emu'])])])])
+
+ [if [ x"$enable_grub_emu_usb" = xyes ]; then
+ # Check for libusb libraries.]
+ AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"],
+ [AC_MSG_ERROR([libusb libraries are required to build `grub-emu' with
USB support])])
+ AC_SUBST([LIBUSB])
+
+ [# Check for headers.]
+ AC_CHECK_HEADERS([usb.h], [],
+ [AC_MSG_ERROR([libusb header file is required to build `grub-emu' with
USB support])])
+ [fi]
[fi]
AC_SUBST([enable_grub_emu])
+AC_SUBST([enable_grub_emu_usb])
AC_ARG_ENABLE([grub-fstest],
[AS_HELP_STRING([--enable-grub-fstest],
Added: trunk/grub2/disk/usbms.c
===================================================================
--- trunk/grub2/disk/usbms.c (rev 0)
+++ trunk/grub2/disk/usbms.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,393 @@
+/* usbms.c - USB Mass Storage Support. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/scsi.h>
+#include <grub/scsicmd.h>
+#include <grub/misc.h>
+
+#define GRUB_USBMS_DIRECTION_BIT 7
+
+/* The USB Mass Storage Command Block Wrapper. */
+struct grub_usbms_cbw
+{
+ grub_uint32_t signature;
+ grub_uint32_t tag;
+ grub_uint32_t transfer_length;
+ grub_uint8_t flags;
+ grub_uint8_t lun;
+ grub_uint8_t length;
+ grub_uint8_t cbwcb[16];
+} __attribute__ ((packed));
+
+struct grub_usbms_csw
+{
+ grub_uint32_t signature;
+ grub_uint32_t tag;
+ grub_uint32_t residue;
+ grub_uint8_t status;
+} __attribute__ ((packed));
+
+struct grub_usbms_dev
+{
+ struct grub_usb_device *dev;
+
+ int luns;
+
+ int interface;
+ struct grub_usb_desc_endp *in;
+ struct grub_usb_desc_endp *out;
+
+ int in_maxsz;
+ int out_maxsz;
+
+ struct grub_usbms_dev *next;
+};
+typedef struct grub_usbms_dev *grub_usbms_dev_t;
+
+static grub_usbms_dev_t grub_usbms_dev_list;
+
+static int devcnt;
+
+static grub_err_t
+grub_usbms_reset (grub_usb_device_t dev, int interface)
+{
+ return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0);
+}
+
+static void
+grub_usbms_finddevs (void)
+{
+ auto int usb_iterate (grub_usb_device_t dev);
+
+ int usb_iterate (grub_usb_device_t usbdev)
+ {
+ grub_usb_err_t err;
+ struct grub_usb_desc_device *descdev = &usbdev->descdev;
+ int i;
+
+ if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0)
+ return 0;
+
+ /* XXX: Just check configuration 0 for now. */
+ for (i = 0; i < usbdev->config[0].descconf->numif; i++)
+ {
+ struct grub_usbms_dev *usbms;
+ struct grub_usb_desc_if *interf;
+ int j;
+ grub_uint8_t luns;
+
+ interf = usbdev->config[0].interf[i].descif;
+
+ /* If this is not a USB Mass Storage device with a supported
+ protocol, just skip it. */
+ if (interf->class != GRUB_USB_CLASS_MASS_STORAGE
+ || interf->subclass != GRUB_USBMS_SUBCLASS_BULK
+ || interf->protocol != GRUB_USBMS_PROTOCOL_BULK)
+ {
+ continue;
+ }
+
+ devcnt++;
+ usbms = grub_malloc (sizeof (struct grub_usbms_dev));
+ if (! usbms)
+ return 1;
+
+ usbms->dev = usbdev;
+ usbms->interface = i;
+ usbms->in = NULL;
+ usbms->out = NULL;
+
+ /* Iterate over all endpoints of this interface, at least a
+ IN and OUT bulk endpoint are required. */
+ for (j = 0; j < interf->endpointcnt; j++)
+ {
+ struct grub_usb_desc_endp *endp;
+ endp = &usbdev->config[0].interf[i].descendp[j];
+
+ if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+ {
+ /* Bulk IN endpoint. */
+ usbms->in = endp;
+ grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
+ usbms->in_maxsz = endp->maxpacket;
+ }
+ else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+ {
+ /* Bulk OUT endpoint. */
+ usbms->out = endp;
+ grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
+ usbms->out_maxsz = endp->maxpacket;
+ }
+ }
+
+ if (!usbms->in || !usbms->out)
+ {
+ grub_free (usbms);
+ return 0;
+ }
+
+ /* Query the amount of LUNs. */
+ err = grub_usb_control_msg (usbdev, 0xA1, 254,
+ 0, i, 1, (char *) &luns);
+ if (err)
+ {
+ /* In case of a stall, clear the stall. */
+ if (err == GRUB_USB_ERR_STALL)
+ {
+ grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3);
+ grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3);
+ }
+
+ /* Just set the amount of LUNs to one. */
+ grub_errno = GRUB_ERR_NONE;
+ usbms->luns = 1;
+ }
+ else
+ usbms->luns = luns;
+
+ /* XXX: Check the magic values, does this really make
+ sense? */
+ grub_usb_control_msg (usbdev, (1 << 6) | 1, 255,
+ 0, i, 0, 0);
+
+ /* XXX: To make Qemu work? */
+ if (usbms->luns == 0)
+ usbms->luns = 1;
+
+ usbms->next = grub_usbms_dev_list;
+ grub_usbms_dev_list = usbms;
+
+ /* XXX: Activate the first configuration. */
+ grub_usb_set_configuration (usbdev, 1);
+
+ /* Bolk-Only Mass Storage Reset, after the reset commands
+ will be accepted. */
+ grub_usbms_reset (usbdev, i);
+
+ return 0;
+ }
+
+ return 0;
+ }
+
+ grub_usb_iterate (usb_iterate);
+}
+
+
+
+static int
+grub_usbms_iterate (int (*hook) (const char *name, int luns))
+{
+ grub_usbms_dev_t p;
+ int cnt = 0;
+
+ for (p = grub_usbms_dev_list; p; p = p->next)
+ {
+ char devname[20];
+ grub_sprintf (devname, "usb%d", cnt);
+
+ if (hook (devname, p->luns))
+ return 1;
+ cnt++;
+ }
+
+ return 0;
+}
+
+static grub_err_t
+grub_usbms_tranfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+ grub_size_t size, char *buf, int read_write)
+{
+ struct grub_usbms_cbw cbw;
+ grub_usbms_dev_t dev = (grub_usbms_dev_t) scsi->data;
+ struct grub_usbms_csw status;
+ static grub_uint32_t tag = 0;
+ grub_usb_err_t err;
+ int retrycnt = 3;
+
+ retry:
+ if (retrycnt == 0)
+ return err;
+
+ /* Setup the request. */
+ grub_memset (&cbw, 0, sizeof (cbw));
+ cbw.signature = grub_cpu_to_le32 (0x43425355);
+ cbw.tag = tag++;
+ cbw.transfer_length = grub_cpu_to_le32 (size);
+ cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT;
+ cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+ cbw.length = cmdsize;
+ grub_memcpy (cbw.cbwcb, cmd, cmdsize);
+
+ /* Write the request. */
+ err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15,
+ sizeof (cbw), (char *) &cbw);
+ if (err)
+ {
+ if (err == GRUB_USB_ERR_STALL)
+ {
+ grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+ goto retry;
+ }
+ return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");;
+ }
+
+ /* Read/write the data. */
+ if (read_write == 0)
+ {
+ err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf);
+ grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL);
+ if (err)
+ {
+ if (err == GRUB_USB_ERR_STALL)
+ {
+ grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+ goto retry;
+ }
+ return grub_error (GRUB_ERR_READ_ERROR,
+ "can't read from USB Mass Storage device");
+ }
+ }
+ else
+ {
+ err = grub_usb_bulk_write (dev->dev, dev->in->endp_addr & 15, size, buf);
+ grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL);
+ if (err)
+ {
+ if (err == GRUB_USB_ERR_STALL)
+ {
+ grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+ goto retry;
+ }
+ return grub_error (GRUB_ERR_WRITE_ERROR,
+ "can't write to USB Mass Storage device");
+ }
+ }
+
+ /* Read the status. */
+ err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15,
+ sizeof (status), (char *) &status);
+ if (err)
+ {
+ if (err == GRUB_USB_ERR_STALL)
+ {
+ grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+ goto retry;
+ }
+ return grub_error (GRUB_ERR_READ_ERROR,
+ "can't read status from USB Mass Storage device");
+ }
+
+ /* XXX: Magic and check this code. */
+ if (status.status == 2)
+ {
+ /* XXX: Phase error, reset device. */
+ grub_usbms_reset (dev->dev, dev->interface);
+ grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+ grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+
+ retrycnt--;
+ if (retrycnt)
+ goto retry;
+ }
+
+ if (status.status)
+ return grub_error (GRUB_ERR_READ_ERROR,
+ "error communication with USB Mass Storage device");
+
+ return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_usbms_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+ grub_size_t size, char *buf)
+{
+ return grub_usbms_tranfer (scsi, cmdsize, cmd, size, buf, 0);
+}
+
+static grub_err_t
+grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+ grub_size_t size, char *buf)
+{
+ return grub_usbms_tranfer (scsi, cmdsize, cmd, size, buf, 1);
+}
+
+static grub_err_t
+grub_usbms_open (const char *name, struct grub_scsi *scsi)
+{
+ grub_usbms_dev_t p;
+ int devnum;
+ int i = 0;
+
+ if (grub_strncmp (name, "usb", 3))
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+ "not a USB Mass Storage device");
+
+ devnum = grub_strtoul (name + 3, NULL, 10);
+ for (p = grub_usbms_dev_list; p; p = p->next)
+ {
+ /* Check if this is the devnumth device. */
+ if (devnum == i)
+ {
+ scsi->data = p;
+ scsi->name = grub_strdup (name);
+ scsi->luns = p->luns;
+ if (! scsi->name)
+ return grub_errno;
+
+ return GRUB_ERR_NONE;
+ }
+
+ i++;
+ }
+
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+ "not a USB Mass Storage device");
+}
+
+static void
+grub_usbms_close (struct grub_scsi *scsi)
+{
+ grub_free (scsi->name);
+}
+
+static struct grub_scsi_dev grub_usbms_dev =
+ {
+ .name = "usb",
+ .iterate = grub_usbms_iterate,
+ .open = grub_usbms_open,
+ .close = grub_usbms_close,
+ .read = grub_usbms_read,
+ .write = grub_usbms_write
+ };
+
+GRUB_MOD_INIT(usbms)
+{
+ grub_usbms_finddevs ();
+ grub_scsi_dev_register (&grub_usbms_dev);
+}
+
+GRUB_MOD_FINI(usbms)
+{
+ grub_scsi_dev_unregister (&grub_usbms_dev);
+}
Modified: trunk/grub2/include/grub/err.h
===================================================================
--- trunk/grub2/include/grub/err.h 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/include/grub/err.h 2009-02-08 17:58:32 UTC (rev 1982)
@@ -52,7 +52,8 @@
GRUB_ERR_SYMLINK_LOOP,
GRUB_ERR_BAD_GZIP_DATA,
GRUB_ERR_MENU,
- GRUB_ERR_TIMEOUT
+ GRUB_ERR_TIMEOUT,
+ GRUB_ERR_IO
}
grub_err_t;
Added: trunk/grub2/include/grub/usb.h
===================================================================
--- trunk/grub2/include/grub/usb.h (rev 0)
+++ trunk/grub2/include/grub/usb.h 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,207 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/>.
+ */
+
+#ifndef GRUB_USB_H
+#define GRUB_USB_H 1
+
+#include <grub/usbdesc.h>
+#include <grub/usbtrans.h>
+
+typedef struct grub_usb_device *grub_usb_device_t;
+typedef struct grub_usb_controller *grub_usb_controller_t;
+typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t;
+
+typedef enum
+ {
+ GRUB_USB_ERR_NONE,
+ GRUB_USB_ERR_INTERNAL,
+ GRUB_USB_ERR_STALL,
+ GRUB_USB_ERR_DATA,
+ GRUB_USB_ERR_NAK,
+ GRUB_USB_ERR_BABBLE,
+ GRUB_USB_ERR_TIMEOUT,
+ GRUB_USB_ERR_BITSTUFF
+ } grub_usb_err_t;
+
+typedef enum
+ {
+ GRUB_USB_SPEED_NONE,
+ GRUB_USB_SPEED_LOW,
+ GRUB_USB_SPEED_FULL,
+ GRUB_USB_SPEED_HIGH
+ } grub_usb_speed_t;
+
+/* Call HOOK with each device, until HOOK returns non-zero. */
+int grub_usb_iterate (int (*hook) (grub_usb_device_t dev));
+
+grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev);
+
+grub_usb_err_t grub_usb_get_descriptor (grub_usb_device_t dev,
+ grub_uint8_t type, grub_uint8_t index,
+ grub_size_t size, char *data);
+
+struct grub_usb_desc_endp *
+grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr);
+
+grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint);
+
+
+grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev,
+ int configuration);
+
+grub_usb_err_t grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index,
+ int langid, char **string);
+
+void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb);
+
+void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb);
+
+int grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev));
+
+
+grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t
reqtype,
+ grub_uint8_t request, grub_uint16_t value,
+ grub_uint16_t index, grub_size_t size,
+ char *data);
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+ int endpoint, grub_size_t size, char *data);
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+ int endpoint, grub_size_t size, char *data);
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller);
+
+
+/* XXX: All handled by libusb for now. */
+struct grub_usb_controller_dev
+{
+ /* The device name. */
+ const char *name;
+
+ int (*iterate) (int (*hook) (grub_usb_controller_t dev));
+
+ grub_usb_err_t (*transfer) (grub_usb_controller_t dev,
+ grub_usb_transfer_t transfer);
+
+ int (*hubports) (grub_usb_controller_t dev);
+
+ grub_err_t (*portstatus) (grub_usb_controller_t dev, unsigned int port,
+ unsigned int enable);
+
+ grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port);
+
+ /* The next host controller. */
+ struct grub_usb_controller_dev *next;
+};
+
+struct grub_usb_controller
+{
+ /* The underlying USB Host Controller device. */
+ grub_usb_controller_dev_t dev;
+
+ /* Data used by the USB Host Controller Driver. */
+ void *data;
+};
+
+
+struct grub_usb_interface
+{
+ struct grub_usb_desc_if *descif;
+
+ struct grub_usb_desc_endp *descendp;
+};
+
+struct grub_usb_configuration
+{
+ /* Configuration descriptors . */
+ struct grub_usb_desc_config *descconf;
+
+ /* Interfaces associated to this configuration. */
+ struct grub_usb_interface interf[32];
+};
+
+struct grub_usb_device
+{
+ /* The device descriptor of this device. */
+ struct grub_usb_desc_device descdev;
+
+ /* The controller the device is connected to. */
+ struct grub_usb_controller controller;
+
+ /* Device configurations (after opening the device). */
+ struct grub_usb_configuration config[8];
+
+ /* Device address. */
+ int addr;
+
+ /* Device speed. */
+ grub_usb_speed_t speed;
+
+ /* All desciptors are read if this is set to 1. */
+ int initialized;
+
+ /* Data toggle values (used for bulk transfers only). */
+ int toggle[16];
+
+ /* Device-specific data. */
+ void *data;
+};
+
+
+
+typedef enum
+ {
+ GRUB_USB_CLASS_NOTHERE,
+ GRUB_USB_CLASS_AUDIO,
+ GRUB_USB_CLASS_COMMUNICATION,
+ GRUB_USB_CLASS_HID,
+ GRUB_USB_CLASS_XXX,
+ GRUB_USB_CLASS_PHYSICAL,
+ GRUB_USB_CLASS_IMAGE,
+ GRUB_USB_CLASS_PRINTER,
+ GRUB_USB_CLASS_MASS_STORAGE,
+ GRUB_USB_CLASS_HUB,
+ GRUB_USB_CLASS_DATA_INTERFACE,
+ GRUB_USB_CLASS_SMART_CARD,
+ GRUB_USB_CLASS_CONTENT_SECURITY,
+ GRUB_USB_CLASS_VIDEO
+ } grub_usb_classes_t;
+
+typedef enum
+ {
+ GRUB_USBMS_SUBCLASS_BULK = 0x06
+ } grub_usbms_subclass_t;
+
+typedef enum
+ {
+ GRUB_USBMS_PROTOCOL_BULK = 0x50
+ } grub_usbms_protocol_t;
+
+static inline struct grub_usb_desc_if *
+grub_usb_get_config_interface (struct grub_usb_desc_config *config)
+{
+ struct grub_usb_desc_if *interf;
+
+ interf = (struct grub_usb_desc_if *) (sizeof (*config) + (char *) config);
+ return interf;
+}
+
+#endif /* GRUB_USB_H */
Added: trunk/grub2/include/grub/usbdesc.h
===================================================================
--- trunk/grub2/include/grub/usbdesc.h (rev 0)
+++ trunk/grub2/include/grub/usbdesc.h 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,119 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/>.
+ */
+
+#ifndef GRUB_USBDESC_H
+#define GRUB_USBDESC_H 1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+typedef enum {
+ GRUB_USB_DESCRIPTOR_DEVICE = 1,
+ GRUB_USB_DESCRIPTOR_CONFIG,
+ GRUB_USB_DESCRIPTOR_STRING,
+ GRUB_USB_DESCRIPTOR_INTERFACE,
+ GRUB_USB_DESCRIPTOR_ENDPOINT,
+ GRUB_USB_DESCRIPTOR_HUB = 0x29
+} grub_usb_descriptor_t;
+
+struct grub_usb_desc_device
+{
+ grub_uint8_t length;
+ grub_uint8_t type;
+ grub_uint16_t usbrel;
+ grub_uint8_t class;
+ grub_uint8_t subclass;
+ grub_uint8_t protocol;
+ grub_uint8_t maxsize0;
+ grub_uint16_t vendorid;
+ grub_uint16_t prodid;
+ grub_uint16_t devrel;
+ grub_uint8_t strvendor;
+ grub_uint8_t strprod;
+ grub_uint8_t strserial;
+ grub_uint8_t configcnt;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_config
+{
+ grub_uint8_t length;
+ grub_uint8_t type;
+ grub_uint16_t totallen;
+ grub_uint8_t numif;
+ grub_uint8_t config;
+ grub_uint8_t strconfig;
+ grub_uint8_t attrib;
+ grub_uint8_t maxpower;
+} __attribute__ ((packed));
+
+#if 0
+struct grub_usb_desc_ifassosiation
+{
+ grub_uint8_t length;
+ grub_uint8_t type;
+ grub_uint8_t firstif;
+ grub_uint8_t ifcnt;
+ grub_uint8_t class;
+ grub_uint8_t subclass;
+ grub_uint8_t protocol;
+ grub_uint8_t function;
+} __attribute__ ((packed));
+#endif
+
+struct grub_usb_desc_if
+{
+ grub_uint8_t length;
+ grub_uint8_t type;
+ grub_uint8_t ifnum;
+ grub_uint8_t altsetting;
+ grub_uint8_t endpointcnt;
+ grub_uint8_t class;
+ grub_uint8_t subclass;
+ grub_uint8_t protocol;
+ grub_uint8_t strif;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_endp
+{
+ grub_uint8_t length;
+ grub_uint8_t type;
+ grub_uint8_t endp_addr;
+ grub_uint8_t attrib;
+ grub_uint16_t maxpacket;
+ grub_uint8_t interval;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_str
+{
+ grub_uint8_t length;
+ grub_uint8_t type;
+ grub_uint16_t str[0];
+} __attribute__ ((packed));
+
+struct grub_usb_usb_hubdesc
+{
+ grub_uint8_t length;
+ grub_uint8_t type;
+ grub_uint8_t portcnt;
+ grub_uint16_t characteristics;
+ grub_uint8_t pwdgood;
+ grub_uint8_t current;
+ /* Removable and power control bits follow. */
+} __attribute__ ((packed));
+
+#endif /* GRUB_USBDESC_H */
Added: trunk/grub2/include/grub/usbtrans.h
===================================================================
--- trunk/grub2/include/grub/usbtrans.h (rev 0)
+++ trunk/grub2/include/grub/usbtrans.h 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,107 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/>.
+ */
+
+#ifndef GRUB_USBTRANS_H
+#define GRUB_USBTRANS_H 1
+
+typedef enum
+ {
+ GRUB_USB_TRANSFER_TYPE_IN,
+ GRUB_USB_TRANSFER_TYPE_OUT,
+ GRUB_USB_TRANSFER_TYPE_SETUP
+ } grub_transfer_type_t;
+
+typedef enum
+ {
+ GRUB_USB_TRANSACTION_TYPE_CONTROL,
+ GRUB_USB_TRANSACTION_TYPE_BULK
+ } grub_transaction_type_t;
+
+struct grub_usb_transaction
+{
+ int size;
+ int toggle;
+ grub_transfer_type_t pid;
+ char *data;
+};
+typedef struct grub_usb_transaction *grub_usb_transaction_t;
+
+struct grub_usb_transfer
+{
+ int devaddr;
+
+ int endpoint;
+
+ int size;
+
+ int transcnt;
+
+ int max;
+
+ grub_transaction_type_t type;
+
+ struct grub_usb_device *dev;
+
+ struct grub_usb_transaction *transactions;
+};
+typedef struct grub_usb_transfer *grub_usb_transfer_t;
+
+
+#define GRUB_USB_REQTYPE_IN (1 << 7)
+#define GRUB_USB_REQTYPE_OUT (0 << 7)
+#define GRUB_USB_REQTYPE_STANDARD (0 << 5)
+#define GRUB_USB_REQTYPE_CLASS (1 << 5)
+#define GRUB_USB_REQTYPE_VENDOR (2 << 5)
+#define GRUB_USB_REQTYPE_TARGET_DEV (0 << 0)
+#define GRUB_USB_REQTYPE_TARGET_INTERF (1 << 0)
+#define GRUB_USB_REQTYPE_TARGET_ENDP (2 << 0)
+#define GRUB_USB_REQTYPE_TARGET_OTHER (3 << 0)
+
+#define GRUB_USB_REQ_GET_STATUS 0x00
+#define GRUB_USB_REQ_CLEAR_FEATURE 0x01
+#define GRUB_USB_REQ_SET_FEATURE 0x03
+#define GRUB_USB_REQ_SET_ADDRESS 0x05
+#define GRUB_USB_REQ_GET_DESCRIPTOR 0x06
+#define GRUB_USB_REQ_SET_DESCRIPTOR 0x07
+#define GRUB_USB_REQ_GET_CONFIGURATION 0x08
+#define GRUB_USB_REQ_SET_CONFIGURATION 0x09
+#define GRUB_USB_REQ_GET_INTERFACE 0x0A
+#define GRUB_USB_REQ_SET_INTERFACE 0x0B
+#define GRUB_USB_REQ_SYNC_FRAME 0x0C
+
+#define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00
+
+#define GRUB_USB_FEATURE_ENDP_HALT 0x01
+#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x02
+#define GRUB_USB_FEATURE_TEST_MODE 0x04
+
+#define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0)
+#define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9)
+#define GRUB_USB_HUB_STATUS_HIGHSPEED (1 << 10)
+
+struct grub_usb_packet_setup
+{
+ grub_uint8_t reqtype;
+ grub_uint8_t request;
+ grub_uint16_t value;
+ grub_uint16_t index;
+ grub_uint16_t length;
+} __attribute__((packed));
+
+
+#endif /* GRUB_USBTRANS_H */
Modified: trunk/grub2/util/grub-emu.c
===================================================================
--- trunk/grub2/util/grub-emu.c 2009-02-08 10:52:03 UTC (rev 1981)
+++ trunk/grub2/util/grub-emu.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -187,6 +187,10 @@
/* XXX: This is a bit unportable. */
grub_util_biosdisk_init (dev_map);
+#if HAVE_USB_H
+ grub_libusb_init ();
+#endif
+
grub_init_all ();
/* Make sure that there is a root device. */
Added: trunk/grub2/util/usb.c
===================================================================
--- trunk/grub2/util/usb.c (rev 0)
+++ trunk/grub2/util/usb.c 2009-02-08 17:58:32 UTC (rev 1982)
@@ -0,0 +1,191 @@
+/* usb.c -- libusb USB support for GRUB. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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 <config.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <usb.h>
+#include <grub/usb.h>
+#include <grub/dl.h>
+
+
+static struct grub_usb_controller_dev usb_controller =
+{
+ .name = "libusb"
+};
+
+static struct grub_usb_device *grub_usb_devs[128];
+
+struct usb_bus *busses;
+
+static grub_err_t
+grub_libusb_devices (void)
+
+{
+ struct usb_bus *bus;
+ int last = 0;
+
+ busses = usb_get_busses();
+
+ for (bus = busses; bus; bus = bus->next)
+ {
+ struct usb_device *usbdev;
+ struct grub_usb_device *dev;
+
+ for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
+ {
+ struct usb_device_descriptor *desc = &usbdev->descriptor;
+
+ if (! desc->bcdUSB)
+ continue;
+
+ dev = grub_malloc (sizeof (*dev));
+ if (! dev)
+ return grub_errno;
+
+ dev->data = usbdev;
+
+ /* Fill in all descriptors. */
+ grub_usb_device_initialize (dev);
+
+ /* Register the device. */
+ grub_usb_devs[last++] = dev;
+ }
+ }
+
+ return GRUB_USB_ERR_NONE;
+}
+
+grub_err_t
+grub_libusb_init (void)
+{
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ if (grub_libusb_devices ())
+ return grub_errno;
+
+ grub_usb_controller_dev_register (&usb_controller);
+
+ return 0;
+}
+
+grub_err_t
+grub_libusb_fini (void)
+{
+ return 0;
+}
+
+
+int
+grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
+{
+ int i;
+
+ for (i = 0; i < 128; i++)
+ {
+ if (grub_usb_devs[i])
+ {
+ if (hook (grub_usb_devs[i]))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused)))
+{
+ return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
+ grub_uint8_t request, grub_uint16_t value,
+ grub_uint16_t index, grub_size_t size, char *data)
+{
+ usb_dev_handle *devh;
+ struct usb_device *d = dev->data;
+
+ devh = usb_open (d);
+ if (usb_control_msg (devh, reqtype, request,
+ value, index, data, size, 20) < 0)
+ {
+ usb_close (devh);
+ return GRUB_USB_ERR_STALL;
+ }
+
+ usb_close (devh);
+
+ return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+ int endpoint, grub_size_t size, char *data)
+{
+ usb_dev_handle *devh;
+ struct usb_device *d = dev->data;
+
+ devh = usb_open (d);
+ if (usb_claim_interface (devh, 0) < 1)
+ {
+ usb_close (devh);
+ return GRUB_USB_ERR_STALL;
+ }
+
+ if (usb_bulk_read (devh, endpoint, data, size, 20) < 1)
+ {
+ usb_close (devh);
+ return GRUB_USB_ERR_STALL;
+ }
+
+ usb_release_interface (devh, 0);
+ usb_close (devh);
+
+ return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+ int endpoint, grub_size_t size, char *data)
+{
+ usb_dev_handle *devh;
+ struct usb_device *d = dev->data;
+
+ devh = usb_open (d);
+ if (usb_claim_interface (devh, 0) < 0)
+ goto fail;
+
+ if (usb_bulk_write (devh, endpoint, data, size, 20) < 0)
+ goto fail;
+
+ if (usb_release_interface (devh, 0) < 0)
+ goto fail;
+
+ usb_close (devh);
+
+ return GRUB_USB_ERR_NONE;
+
+ fail:
+ usb_close (devh);
+ return GRUB_USB_ERR_STALL;
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [1982] 2009-02-08 Marco Gerards <address@hidden>,
Robert Millan <=