Re: USB4BSD (USB2): Microsoft 4000 keyboard unusable

From: Hans Petter Selasky <hselasky_at_c2i.net>
Date: Fri, 7 Nov 2008 18:09:04 +0100
On Friday 07 November 2008, Jeremy Chadwick wrote:
> On Fri, Nov 07, 2008 at 11:38:49AM +0300, Eygene Ryabinkin wrote:
> > Thu, Nov 06, 2008 at 11:52:32PM -0800, Jeremy Chadwick wrote:
> > [...]
> >
> > > Everything built (csup date: 2008/11/06 ~2200 PST) fine, no issues --
> > > until I noticed my USB keyboard didn't function any longer.
> > >
> > > During boot0/boot2/loader, the keyboard functions (as expected, re: USB
> > > Legacy option is enabled in my BIOS), and the keyboard LEDs are lit as
> > > expected.  The kernel loads, some drivers initialise, and the LEDs go
> > > off.  Once the USB2 stack loads, the keyboard LEDs turn back up, but as
> > > stated, no keypresses are registered.  I was forced to hook up a PS/2
> > > keyboard.
> >

You are using 64-bit architecture - right?

Then you need the following patch to usb2_busdma.c:

http://perforce.freebsd.org/chv.cgi?CH=152624
       
        Fix some problems related to busdma:
        Need to unload DMA maps before re-use!
        Fix a corner case when loading zero bytes.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_busdma.c#10 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_busdma.c#10 (text+ko) 
====

_at__at_ -597,6 +597,12 _at__at_
                        uptag = pc->tag_parent;
 
                        /*
+                        * We have to unload the previous loaded DMA
+                        * pages before trying to load a new one!
+                        */
+                       bus_dmamap_unload(pc->tag, pc->map);
+
+                       /*
                         * Try to load memory into DMA.
                         */
                        err = bus_dmamap_load(
_at__at_ -612,6 +618,12 _at__at_
                } else {
 
                        /*
+                        * We have to unload the previous loaded DMA
+                        * pages before trying to load a new one!
+                        */
+                       bus_dmamap_unload(pc->tag, pc->map);
+
+                       /*
                         * Try to load memory into DMA. The callback
                         * will be called in all cases:
                         */
_at__at_ -639,6 +651,10 _at__at_
 void
 usb2_pc_cpu_invalidate(struct usb2_page_cache *pc)
 {
+       if (pc->page_offset_end == pc->page_offset_buf) {
+               /* nothing has been loaded into this page cache! */
+               return;
+       }
        bus_dmamap_sync(pc->tag, pc->map,
            BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
        return;
_at__at_ -650,6 +666,10 _at__at_
 void
 usb2_pc_cpu_flush(struct usb2_page_cache *pc)
 {
+       if (pc->page_offset_end == pc->page_offset_buf) {
+               /* nothing has been loaded into this page cache! */
+               return;
+       }
        bus_dmamap_sync(pc->tag, pc->map,
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
        return;
_at__at_ -953,6 +973,12 _at__at_
 
        if (size > 0) {
 
+               /*
+                * We have to unload the previous loaded DMA
+                * pages before trying to load a new one!
+                */
+               bus_dmamap_unload(pc->tag, pc->map);
+
                /* try to load memory into DMA using using no wait option */
                if (bus_dmamap_load(pc->tag, pc->map, pc->buffer,
                    size, NULL, BUS_DMA_NOWAIT)) {
_at__at_ -990,6 +1016,10 _at__at_
 
        len = pc->page_offset_end - pc->page_offset_buf;
 
+       if (len == 0) {
+               /* nothing has been loaded into this page cache */
+               return;
+       }
        bus_dmamap_sync(pc->tag, pc->map, 0, len,
            BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
        return;
_at__at_ -1005,6 +1035,10 _at__at_
 
        len = pc->page_offset_end - pc->page_offset_buf;
 
+       if (len == 0) {
+               /* nothing has been loaded into this page cache */
+               return;
+       }
        bus_dmamap_sync(pc->tag, pc->map, 0, len,
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
        return;

Best regards
  HPS
Received on Fri Nov 07 2008 - 16:06:58 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:37 UTC