Hi Vladimir,
there is the patch with @Rock changes.
I hope I didn't make some mistake during cleanup/macroify...
You may note some additional cosmetic changes:
1.
...
+ /* Finish HC reset, HC remains disabled */
+ grub_uhci_writereg16(u, GRUB_UHCI_REG_USBCMD, 0);
+ /* Read back to be sure PCI write is done */
+ grub_uhci_readreg16(u, GRUB_UHCI_REG_USBCMD);
...
I think it is more safe to ensure the command is written into PCI
register before executing next code.
2.
- /* Make sure UHCI is disabled! */
- grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
-
It is not necessary yet because UHCI is disabled sooner in code which is
listed above in point 1.
3.
- grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7));
+ grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD,
+ GRUB_UHCI_CMD_RUN_STOP | GRUB_UHCI_CMD_MAXP);
Some very small cleanup of previous code...
I very shortly tested this patch, it seems to be working OK.
Best regards,
Ales
Vladimir 'φ-coder/phcoder' Serbinenko píše v Ne 21. 08. 2011 v 18:10
+0200:
> On 20.08.2011 23:45, Aleš Nesrsta wrote:
> > Hi everybody,
> >
> > could anybody test changes from Cui Lei (see below) in uhci.c - if they
> > are generally working and does not have some negative effect on machines
> > with "normal" BIOS etc. ?
> >
> > Maybe such changes are related only to coreboot and some special use
> > case/platform, but probably they are related to needed change of UHCI
> > controller ownership and should be included into uhci.c code.
> >
> I don't think it is. The difference is that coreboot doesn't use USB
> itself so it's initialised but disabled initially which I expect also to
> happen with some older BIOSes so this code is perfectly ok to be added
> generically.
> @Rock or Aleš: Could someone of you clean this up (macroify and comment
> style mainly) and supply as a .diff ?
> > Regards,
> > Ales
> >
> > -------- Přeposlaná zpráva --------
> > Od: Cui Lei <[email protected]>
> > Komu: Aleš Nesrsta <[email protected]>
> > Kopie: The development of GNU GRUB <[email protected]>
> > Předmět: [Resolved] Grub2 can not detect usb disk
> > Datum: Fri, 19 Aug 2011 10:58:00 +0800
> >
> > Thank you for your help, very much! ^_^
> > This problem have been resolved and I can usb the usb_keyborard under
> > grub-shell and I can boot ubuntu11.04 from usb disk.
> > My mainboard is via 8595a, the usb controller is uhci.
> > I resolved it by add these code in the grub-core/bus/usb/uhci.c:
> >
> > (1)
> > 182 /*Set bus master*/
> > 183 addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
> > 184 grub_uint16_t val = grub_pci_read_word(addr);
> > 185 val = (val & ~0) | GRUB_PCI_COMMAND_BUS_MASTER;
> > 186 grub_pci_write_word(addr, val);
> >
> > (2)
> > 203 // Reset PIRQ and SMI
> > 204 addr = grub_pci_make_address (dev, 0xC0);
> > //USBLEGSUP 0xc0
> > 205 grub_pci_write_word(addr, 0x8f00); //USBLEGSUP_RWC
> > 0x8f00 /* the R/WC bits */
> > 206 // Reset the HC
> > 207 grub_uhci_writereg16(u, GRUB_UHCI_REG_USBCMD, 0x0002);
> > //USBCMD_HCRESET 0x0002
> > 208 grub_millisleep(5);
> > 209 // Disable interrupts and commands (just to be safe).
> > 210 grub_outw (0, u->iobase + 4); //USBINTR 4 /*Interrupt
> > enable register*/
> > 211 grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
> >
> > I don't know whether it is useful to the other one, but may be a reference.
> >
> > BRs,
> >
> > Rock.
> >
> >> Hi,
> >>
> >> I am afraid, I maybe will not help You too much but I try it:
> >>
> >> I shortly looked into ML to Your posts. As I saw short part of debug
> >> output in one of Your e-mail, GRUB freezes when it wants to get device
> >> descriptor - more precisely, when it requests first 8 bytes of device
> >> descriptor. It is the first thing which is done after address is
> >> assigned to the device.
> >>
> >> So, it looks like device does not set address properly (even if control
> >> message Set Address returns success) or happened something else what
> >> prevent device to respond (but I don't know what...).
> >>
> >> For the first try You can increase related delays in usbhub.c:
> >>
> >> ...
> >> /* Wait "recovery interval", spec. says 2ms */
> >> grub_millisleep (2);<<<<---- HERE (try 4ms or more)
> >>
> >> grub_usb_device_attach (dev);
> >> ...
> >>
> >> ...
> >> /* Enable the port. */
> >> err = hub->controller->dev->portstatus (hub->controller, portno, 1);
> >> if (err)
> >> return;
> >> hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
> >>
> >> grub_millisleep (10);<<<<---- maybe here also
> >>
> >> /* Enable the port and create a device. */
> >> dev = grub_usb_hub_add_dev (hub->controller, speed, portno, 0);
> >> hub->controller->dev->pending_reset = 0;
> >> if (! dev)
> >> return;
> >> ...
> >>
> >> If this will not help You, I currently have no other idea what could be
> >> the reason of timeout.
> >> I think You don't need EHCI because it looks like Set Address control
> >> message works (at least it does not return error), i.e. You probably
> >> have OHCI or UHCI USB (companion) controller on computer and Your device
> >> is working at full or low speed with Your USB controller.
> >>
> >> By the way, for the first look into ML I did not find which USB
> >> controller You have - OHCI/UHCI ? (which driver/module are You using -
> >> ohci/uhci?) - and which machine/architecture is the computer You are
> >> trying to boot with GRUB2 - ?
> >> I sometimes had some unidentified problems on my UHCI/EHCI controller,
> >> mostly with port powering - UHCI does not have power management but EHCI
> >> does and if EHCI is not properly initialized by BIOS (it could be Your
> >> case with coreboot, maybe ?) then USB ports are not properly powered.
> >> Another BIOS (coreboot?) issue could be improper handling of USB
> >> controller ownership.
> >>
> >> Do You have USB device connected directly into root port or via some USB
> >> hub ? Try to do it in opposite way (i.e. if You are not using the USB
> >> hub, try use it and connect USB device via hub - maybe it helps...)
> >>
> >> Hmmm, I remember now one issue which could be related to Your problem.
> >> On my very old machine with OHCI USB controller some devices are not
> >> working "for the first time". I am still not able to debug why it
> >> happened (it does not happened when full debug is active - so it looks
> >> like it is related to some timing). But I am afraid it will be not Your
> >> case because device stops working after it is recognized, configured,
> >> usbms module loaded and GRUB USB device usb0 created.
> >> But - try load ohci/uhci module when USB disk is connected and then
> >> disconnect and connect it again after few seconds. In my case device
> >> becomes working as new usb device (i.e. usb1).
> >>
> >> Additionally, lot of manufacturers does not follow USB or USBMS
> >> specifications, as You can read in Linux source code of USB controllers
> >> and USB mass storage devices and related documentation.
> >> Did You tried more different USB mass storage devices ?
> >> What is manufacturer& type of Your USB mass storage device ?
> >>
> >> Of course, You can also try EHCI driver, it maybe can solve Your problem
> >> because of little bit different ports/devices handling. But EHCI driver
> >> is currently highly experimental, it still exists only as uncorrected
> >> and not accepted "patch". I have to do some improvement but I don't have
> >> sufficient time still, unfortunately...
> >> If You want try to use it, You can get my patch from ML (sent at
> >> 25.6.2011) and use it with related source code trunk branch revision
> >> (maybe also any later or current revision, because USB parts of GRUB are
> >> not frequently changed). Please also read about know issue and another
> >> limitations of the "zero version" of EHCI driver - e.g. it may not work
> >> if Your PC is not x86 machine or USB registers are mapped above 4GB etc.
> >>
> >> Sorry if You will wait longer time for my response in future - I don't
> >> check the post so often and additionally currently I am (and probably
> >> will be) longer time too busy - I am not regular GRUB2 contributor, I do
> >> something for GRUB2 USB part only time to time...
> >>
> >> BRs,
> >> Ales
> >>
> >>
> >> Cui Lei píše v Út 09. 08. 2011 v 11:05 +0800:
> >>> Hi Aleš,
> >>> I am trying to boot OS from USB disk, I use coreboot-v4 with grub2 as
> >>> payload, but my usb disk can not been
> >>> detect. I try to use usb-keyboard, it is not working. I know you are
> >>> working on the EHCI driver from Vladimir ,
> >>> could you give me some advices? Vladimir said it may need EHCI driver,
> >>> but I think the usb device should run
> >>> with low-speed or full-speed if no EHCI driver.C
> >>>
> >>> Looking forward to your reply.
> >>> BRs,
> >>> Rock Cui.
> >>>
> >>>
> >
> >
> >
> >
> >
> > _______________________________________________
> > Grub-devel mailing list
> > [email protected]
> > https://lists.gnu.org/mailman/listinfo/grub-devel
>
>
> _______________________________________________
> Grub-devel mailing list
> [email protected]
> https://lists.gnu.org/mailman/listinfo/grub-devel
diff -purB ./grub/grub-core/bus/usb/uhci.c ./grub_patched/grub-core/bus/usb/uhci.c
--- ./grub/grub-core/bus/usb/uhci.c 2011-08-26 10:21:39.000000000 +0200
+++ ./grub_patched/grub-core/bus/usb/uhci.c 2011-08-26 11:29:52.000000000 +0200
@@ -36,11 +36,33 @@ GRUB_MOD_LICENSE ("GPLv3+");
typedef enum
{
GRUB_UHCI_REG_USBCMD = 0x00,
+ GRUB_UHCI_REG_USBINTR = 0x04,
GRUB_UHCI_REG_FLBASEADD = 0x08,
GRUB_UHCI_REG_PORTSC1 = 0x10,
- GRUB_UHCI_REG_PORTSC2 = 0x12
+ GRUB_UHCI_REG_PORTSC2 = 0x12,
+ GRUB_UHCI_REG_USBLEGSUP = 0xc0
} grub_uhci_reg_t;
+/* R/WC legacy support bits */
+#define GRUB_UHCI_LEGSUP_END_A20GATE (1 << 15)
+#define GRUB_UHCI_TRAP_BY_64H_WSTAT (1 << 11)
+#define GRUB_UHCI_TRAP_BY_64H_RSTAT (1 << 10)
+#define GRUB_UHCI_TRAP_BY_60H_WSTAT (1 << 9)
+#define GRUB_UHCI_TRAP_BY_60H_RSTAT (1 << 8)
+
+/* Reset all legacy support - clear all R/WC bits and all R/W bits */
+#define GRUB_UHCI_RESET_LEGSUP_SMI ( GRUB_UHCI_LEGSUP_END_A20GATE \
+ | GRUB_UHCI_TRAP_BY_64H_WSTAT \
+ | GRUB_UHCI_TRAP_BY_64H_RSTAT \
+ | GRUB_UHCI_TRAP_BY_60H_WSTAT \
+ | GRUB_UHCI_TRAP_BY_60H_RSTAT )
+
+/* Some UHCI commands */
+#define GRUB_UHCI_CMD_RUN_STOP (1 << 0)
+#define GRUB_UHCI_CMD_HCRESET (1 << 1)
+#define GRUB_UHCI_CMD_MAXP (1 << 7)
+
+/* Important bits in structures */
#define GRUB_UHCI_LINK_TERMINATE 1
#define GRUB_UHCI_LINK_QUEUE_HEAD 2
@@ -181,6 +203,11 @@ grub_uhci_pci_iter (grub_pci_device_t de
if (class != 0x0c || subclass != 0x03 || interf != 0x00)
return 0;
+ /* Set bus master - needed for coreboot or broken BIOSes */
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
+ grub_pci_write_word(addr,
+ GRUB_PCI_COMMAND_BUS_MASTER | grub_pci_read_word(addr));
+
/* Determine IO base address. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4);
base = grub_pci_read (addr);
@@ -195,6 +222,19 @@ grub_uhci_pci_iter (grub_pci_device_t de
u->iobase = base & GRUB_UHCI_IOMASK;
+ /* Reset PIRQ and SMI */
+ addr = grub_pci_make_address (dev, GRUB_UHCI_REG_USBLEGSUP);
+ grub_pci_write_word(addr, GRUB_UHCI_RESET_LEGSUP_SMI);
+ /* Reset the HC */
+ grub_uhci_writereg16(u, GRUB_UHCI_REG_USBCMD, GRUB_UHCI_CMD_HCRESET);
+ grub_millisleep(5);
+ /* Disable interrupts and commands (just to be safe) */
+ grub_uhci_writereg16(u, GRUB_UHCI_REG_USBINTR, 0);
+ /* Finish HC reset, HC remains disabled */
+ grub_uhci_writereg16(u, GRUB_UHCI_REG_USBCMD, 0);
+ /* Read back to be sure PCI write is done */
+ grub_uhci_readreg16(u, GRUB_UHCI_REG_USBCMD);
+
/* Reserve a page for the frame list. */
u->framelist = grub_memalign (4096, 4096);
if (! u->framelist)
@@ -252,9 +292,6 @@ grub_uhci_pci_iter (grub_pci_device_t de
u->td[N_TD - 2].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. */
@@ -285,7 +322,8 @@ grub_uhci_pci_iter (grub_pci_device_t de
u->qh[N_QH - 1].linkptr = 1;
/* Enable UHCI again. */
- grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7));
+ grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD,
+ GRUB_UHCI_CMD_RUN_STOP | GRUB_UHCI_CMD_MAXP);
/* UHCI is initialized and ready for transfers. */
grub_dprintf ("uhci", "UHCI initialized\n");
_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel