Dne 19.12.2013 12:33, Melki Christian (consultant) napsal(a):
>...
> I'm not an USB expert. :)
In this case we are two... :)


According to your patch:
Even if this patch looks good for me, I am afraid it is not good way to
handle xHCI from EHCI module.

From my point of view it is maybe little bit better to prepare some
"empty" skeleton of xHCI module and include it in GRUB.
Such "driver":
- will do the thing of your patch only
- will be loaded manually only if necessary (or automatically by some
hardcoded dependency on EHCI module - ? In such case it probably should
include also some Product/Vendor filter or whatever else...)
- could be more easily substituted by real xHCI driver module

My initial simple proposal of "empty" xHCI module, based on your e-mail
and patch, is included.
Note: This is proposal code only, I didn't compile it nor tested...

BR,
Ales
/* xhci.c - xHCI dummy driver.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2011  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/cpu/io.h>
#include <grub/time.h>
#include <grub/loader.h>
#include <grub/list.h>

GRUB_MOD_LICENSE ("GPLv3+");

/* This module solves only xHCI problem:
 * Machine is cold-booted. - > USB keyboard works in GRUB -> Windows boots ->
 * Windows does warm reboot -> USB keyboard does not work in GRUB.
 * This only happens in the ports marked superspeed on the machine.
 * The problem is that Windows seems to leave the the SS ports in SS mode
 * when rebooting and a BIOS bug(?) on warm boot leads to not setting
 * the SS ports in 2.0 mode.
 */

/* Identification values */
#define GRUB_XHCI_CLASS_CODE 0x0c0330
#define GRUB_XHCI_SBRN_VALUE 0x30

#define GRUB_XHCI_PCI_XUSB2PR    0xD0
#define GRUB_XHCI_PCI_USB3_PSSEN 0xD8

/* PCI iteration function... */
static int
grub_xhci_pci_iter (grub_pci_device_t dev,
  grub_pci_id_t pciid __attribute__ ((unused)),
  void __attribute__ ((unused)) *data)
{
  grub_pci_address_t addr;
  grub_uint32_t class_code;
  grub_uint8_t release;
  
  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
  class_code = grub_pci_read (addr) >> 8;

  /* If this is not an XHCI controller, just return.  */
  if (class_code != GRUB_XHCI_CLASS_CODE)
    return 0;

  /* Check Serial Bus Release Number */
  addr = grub_pci_make_address (dev, GRUB_XHCI_PCI_SBRN_REG);
  release = grub_pci_read_byte (addr);
  if (release != GRUB_XHCI_SBRN_VALUE)
    return 0;

  /* Since GRUB does not currently handle xHCI we need
   * to make sure it is disabled and the ports put in 2.0 mode.
   * To be removed when xHCI is properly introduced.
   */
  addr = grub_pci_make_address (dev, GRUB_XHCI_PCI_USB3_PSSEN);
  grub_pci_write_word (addr, 0x0);
  grub_pci_read_word(addr);
  addr = grub_pci_make_address (dev, GRUB_XHCI_PCI_XUSB2PR);
  grub_pci_write_word (addr, 0x0);
  grub_pci_read_word(addr);

  return 0;
}


static int
grub_xhci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data)
{
  return 0;
}


static grub_usb_err_t
grub_xhci_setup_transfer (grub_usb_controller_t dev,
  grub_usb_transfer_t transfer)
{
  if (dev && transfer) {}
  
  return GRUB_USB_ERR_NONE;
}


static grub_usb_err_t
grub_xhci_check_transfer (grub_usb_controller_t dev,
			  grub_usb_transfer_t transfer, grub_size_t * actual)
{
  if (dev && transfer && actual) {}

  return GRUB_USB_ERR_NONE;
}


static grub_usb_err_t
grub_xhci_cancel_transfer (grub_usb_controller_t dev,
			   grub_usb_transfer_t transfer)
{
  if (dev && transfer) {}

  return GRUB_USB_ERR_NONE;
}


static int
grub_xhci_hubports (grub_usb_controller_t dev)
{
  if (dev) {}

  return 0;
}


static grub_usb_err_t
grub_xhci_portstatus (grub_usb_controller_t dev,
		      unsigned int port, unsigned int enable)
{
  if (dev && port && enable) {}

  return GRUB_USB_ERR_NONE;
}


static grub_usb_speed_t
grub_xhci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
{
  if (dev &&changed) {}

  return GRUB_USB_SPEED_NONE;
}


static grub_err_t
grub_xhci_fini_hw (int noreturn __attribute__ ((unused)))
{
  return GRUB_USB_ERR_NONE;
}


static grub_err_t
grub_xhci_restore_hw (void)
{
  return GRUB_USB_ERR_NONE;
}


static void
grub_xhci_inithw (void)
{
  grub_pci_iterate (grub_xhci_pci_iter, NULL);
}


static struct grub_usb_controller_dev usb_controller = {
  .name = "xhci",
  .iterate = grub_xhci_iterate,
  .setup_transfer = grub_xhci_setup_transfer,
  .check_transfer = grub_xhci_check_transfer,
  .cancel_transfer = grub_xhci_cancel_transfer,
  .hubports = grub_xhci_hubports,
  .portstatus = grub_xhci_portstatus,
  .detect_dev = grub_xhci_detect_dev,
  .max_bulk_tds = 0
};


GRUB_MOD_INIT (xhci)
{
  grub_xhci_inithw ();
}

GRUB_MOD_FINI (xhci)
{
  grub_xhci_fini_hw (0);
}

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to