9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* Re: [9fans] usbd problem
@ 2008-02-12  8:21 Richard Miller
  2008-02-12 13:21 ` erik quanstrom
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Miller @ 2008-02-12  8:21 UTC (permalink / raw)
  To: 9fans, 9fans

Looking at /sys/src/cmd/usb/usbd/usbd.c, I wonder whether
your problem has something to do with these lines?

//unconscionable kludge (testing camera)
if(d->class == 10) setup0(d, RH2D|Rinterface, SET_INTERFACE, 10, 0, 0);


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12  8:21 [9fans] usbd problem Richard Miller
@ 2008-02-12 13:21 ` erik quanstrom
  2008-02-12 21:24   ` Richard Miller
  0 siblings, 1 reply; 29+ messages in thread
From: erik quanstrom @ 2008-02-12 13:21 UTC (permalink / raw)
  To: 9fans

> Looking at /sys/src/cmd/usb/usbd/usbd.c, I wonder whether
> your problem has something to do with these lines?
>
> //unconscionable kludge (testing camera)
> if(d->class == 10) setup0(d, RH2D|Rinterface, SET_INTERFACE, 10, 0, 0);

thanks for the suggestion, but the camera was a red herring.
it was actually the usb key that i'd plugged in.  the key works fine
with xp.  so i engineered a swap of usb keys.  it was dying in
setup0 with Estalled.

shouldn't usbd be resistant to badly-behaving devices?
it seems that any error on any endpoint will topple usbd,
at least during configure.

one final question, is there an advantage to usb/disk creating a fs
that's incompatable with devsd?  it would seem to make booting
from usb root difficult.

- erik


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 13:21 ` erik quanstrom
@ 2008-02-12 21:24   ` Richard Miller
  2008-02-12 21:28     ` geoff
  2008-02-12 21:37     ` erik quanstrom
  0 siblings, 2 replies; 29+ messages in thread
From: Richard Miller @ 2008-02-12 21:24 UTC (permalink / raw)
  To: 9fans

> one final question, is there an advantage to usb/disk creating a fs
> that's incompatable with devsd?  it would seem to make booting
> from usb root difficult.

Do you mean why doesn't the ctl file accept partition commands?
You can always use fs(3) for that.  But usb root is not very
practical anyway, at least with uhci, because of a stubborn
bug in the driver which makes transfers very very slow.  Now
there's ohci support I would be interested to know if that works
at more like normal usb speed.



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 21:24   ` Richard Miller
@ 2008-02-12 21:28     ` geoff
  2008-02-12 21:33       ` Richard Miller
  2008-02-12 21:37     ` erik quanstrom
  1 sibling, 1 reply; 29+ messages in thread
From: geoff @ 2008-02-12 21:28 UTC (permalink / raw)
  To: 9fans

Actually, partfs(8) provides devsd-compatible partitions and is
probably a better choice for this than fs(3).  It wasn't cited in
usbdisk(4)'s SEE ALSO, but it is now.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 21:28     ` geoff
@ 2008-02-12 21:33       ` Richard Miller
  0 siblings, 0 replies; 29+ messages in thread
From: Richard Miller @ 2008-02-12 21:33 UTC (permalink / raw)
  To: 9fans

> Actually, partfs(8) provides devsd-compatible partitions

Cool - I hadn't noticed when that appeared.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 21:24   ` Richard Miller
  2008-02-12 21:28     ` geoff
@ 2008-02-12 21:37     ` erik quanstrom
  2008-02-12 22:18       ` Richard Miller
  1 sibling, 1 reply; 29+ messages in thread
From: erik quanstrom @ 2008-02-12 21:37 UTC (permalink / raw)
  To: 9fans

> Do you mean why doesn't the ctl file accept partition commands?
> You can always use fs(3) for that.  But usb root is not very
> practical anyway, at least with uhci, because of a stubborn
> bug in the driver which makes transfers very very slow.  Now
> there's ohci support I would be interested to know if that works
> at more like normal usb speed.

you're assuming that i want to continue to do i/o once i've booted. :-)
the basic problem is that, e.g., ich9r boards have no pata at all.  it used to
be easy to boot from CF or a DOM.  but that's becoming more of a
problem.  booting from usb might be the only cheep solid-state choice.

geoff pointed out that usb/disk pulls in a lot of stuff and might need
some work to run in the kernel.  so perhaps i don't fully appreciate
how interconnected /dev/usb?, usb/usbd, and usb/disk.  i was under
the impression that usb/disk was just a bit of glue that turns an
endpoint into a block device.

- erik


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 21:37     ` erik quanstrom
@ 2008-02-12 22:18       ` Richard Miller
  2008-02-12 23:05         ` geoff
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Miller @ 2008-02-12 22:18 UTC (permalink / raw)
  To: 9fans

> geoff pointed out that usb/disk pulls in a lot of stuff and might need
> some work to run in the kernel.

Usb root can be done by putting usb/disk and usb/usbd into /boot and
hacking /sys/src/9/boot/local.c a bit.  I tried it once and it worked
albeit slowly.  However, getting 9load to use usb disk would be a
bigger task.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 22:18       ` Richard Miller
@ 2008-02-12 23:05         ` geoff
  2008-02-13  6:31           ` arisawa
  2008-02-13 15:54           ` Richard Miller
  0 siblings, 2 replies; 29+ messages in thread
From: geoff @ 2008-02-12 23:05 UTC (permalink / raw)
  To: 9fans

We added booting via the BIOS to 9load specifically for USB (though it
may have other uses), so that we wouldn't have to add to 9load and
maintain 8,000 lines, and growing, of complex USB code (though that's
likely due to the inherent complexity of USB rather than being the
fault of those who have contributed USB code).  See sdB0 and bios0 in
9load(8).  The BIOSes have been somewhat uncooperative, but if you
make a USB floppy or USB disk be the first item in your BIOS boot
order, remove

*nobiosload=something

from your plan9.ini, see the example in prep(8) for how to prepare
such a USB disk, and the phase of the moon is right, it should work.
It's worked here for us.

If we get an EHCI driver written, this will all become much more
interesting.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 23:05         ` geoff
@ 2008-02-13  6:31           ` arisawa
  2008-02-13  8:25             ` Richard Miller
  2008-02-13 10:58             ` Richard Miller
  2008-02-13 15:54           ` Richard Miller
  1 sibling, 2 replies; 29+ messages in thread
From: arisawa @ 2008-02-13  6:31 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

Hello,

Thank you for working for usb support.

In trying usb/disk I have a question:

term% usb/disk
term% disk/partfs /n/disk/0/data
term% disk/mbr /dev/sdXX/data
term% disk/fdisk -baw /dev/sdXX/data
term% disk/prep /dev/sdXX/plan9
   empty                0 2         (2 sectors, 1.00 KB)
   9fat                 2 30000     (29998 sectors, 14.64 MB)
   fs               30000 256913    (226913 sectors, 110.79 MB)
   nvram           256913 256914    (1 sectors, 512 B )
 >>> q
term% ls -l /dev/sdXX
/dev/sdXX/ctl
/dev/sdXX/data
/dev/sdXX/plan9
term%

Where is 9fat, fs and nvram created by disk/prep?

Kenji Arisawa


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13  6:31           ` arisawa
@ 2008-02-13  8:25             ` Richard Miller
  2008-02-13  8:54               ` arisawa
  2008-02-13 10:58             ` Richard Miller
  1 sibling, 1 reply; 29+ messages in thread
From: Richard Miller @ 2008-02-13  8:25 UTC (permalink / raw)
  To: 9fans

> Where is 9fat, fs and nvram created by disk/prep?

Did you forget the 'w' command?


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13  8:25             ` Richard Miller
@ 2008-02-13  8:54               ` arisawa
  0 siblings, 0 replies; 29+ messages in thread
From: arisawa @ 2008-02-13  8:54 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

Oh yes, I misread the situation:
term% disk/prep /dev/sdXX/plan9
   empty                0 2         (2 sectors, 1.00 KB)
   9fat                 2 30000     (29998 sectors, 14.64 MB)
   fs               30000 256913    (226913 sectors, 110.79 MB)
   nvram           256913 256914    (1 sectors, 512 B )
 >>> q

Thanks.

Kenji Arisawa

On 2008/02/13, at 17:25, Richard Miller wrote:

>> Where is 9fat, fs and nvram created by disk/prep?
>
> Did you forget the 'w' command?


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13  6:31           ` arisawa
  2008-02-13  8:25             ` Richard Miller
@ 2008-02-13 10:58             ` Richard Miller
  2008-02-13 14:13               ` Richard Miller
  1 sibling, 1 reply; 29+ messages in thread
From: Richard Miller @ 2008-02-13 10:58 UTC (permalink / raw)
  To: 9fans

>> Where is 9fat, fs and nvram created by disk/prep?
>
> Did you forget the 'w' command?

Also, after restarting partfs you need to reload the
partition information:

  disk/prep -p /dev/sdXX/data >/dev/sdXX/ctl


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13 10:58             ` Richard Miller
@ 2008-02-13 14:13               ` Richard Miller
  2008-02-13 18:49                 ` geoff
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Miller @ 2008-02-13 14:13 UTC (permalink / raw)
  To: 9fans

I'm not having a good day.  I said:

> Also, after restarting partfs you need to reload the
> partition information:
>
>   disk/prep -p /dev/sdXX/data >/dev/sdXX/ctl

Of course it should be:

    disk/fdisk -p /dev/sdXX/data >/dev/sdXX/ctl
    disk/prep -p /dev/sdXX/plan9 >/dev/sdXX/ctl


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 23:05         ` geoff
  2008-02-13  6:31           ` arisawa
@ 2008-02-13 15:54           ` Richard Miller
  1 sibling, 0 replies; 29+ messages in thread
From: Richard Miller @ 2008-02-13 15:54 UTC (permalink / raw)
  To: 9fans

> We added booting via the BIOS to 9load specifically for USB

Oh yes, I had forgotten that.  None of my machines seem to be
willing to boot from any of my usb flash drives.  However I have
just successfully resurrected my experiment with using a kfs
on usb disk as root - see /contrib/miller/usb/boot for info.
It should work for fossil as well but I haven't tried that.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13 14:13               ` Richard Miller
@ 2008-02-13 18:49                 ` geoff
  0 siblings, 0 replies; 29+ messages in thread
From: geoff @ 2008-02-13 18:49 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 33 bytes --]

Or just run diskparts(8) again.

[-- Attachment #2: Type: message/rfc822, Size: 2682 bytes --]

From: Richard Miller <9fans@hamnavoe.com>
To: 9fans@cse.psu.edu
Subject: Re: [9fans] usbd problem
Date: Wed, 13 Feb 2008 14:13:25 +0000
Message-ID: <a1b163ac177eef58a2790d78855a0edc@hamnavoe.com>

I'm not having a good day.  I said:

> Also, after restarting partfs you need to reload the
> partition information:
>
>   disk/prep -p /dev/sdXX/data >/dev/sdXX/ctl

Of course it should be:

    disk/fdisk -p /dev/sdXX/data >/dev/sdXX/ctl
    disk/prep -p /dev/sdXX/plan9 >/dev/sdXX/ctl

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13 16:37               ` erik quanstrom
@ 2008-02-13 17:09                 ` Sape Mullender
  0 siblings, 0 replies; 29+ messages in thread
From: Sape Mullender @ 2008-02-13 17:09 UTC (permalink / raw)
  To: 9fans

>> > ohci.  oddly, my uhci ich9r machine doesn't recognize
>> > either of my extensive collection of two usb devices.
>>
>> You may be running the usbd with faulty dump.c.  If your
>> devices show up in /dev/usb0/1/status with just one
>> line and 0x000000 for Class/Subclass/Proto, then you're
>> almost certainly running the old dump.c.
>>
>> In dump.c, five lines before the bottom of the file,
>> change len = b[0] - 1 into len = b[0]
>>
>> A new version should already have been posted.
>>
>> 	Sape
>
> unfortunately, that's not the problem.

Try usb/usbd -d -1 -V and send me the output.

	Sape


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13 16:18             ` Sape Mullender
@ 2008-02-13 16:37               ` erik quanstrom
  2008-02-13 17:09                 ` Sape Mullender
  0 siblings, 1 reply; 29+ messages in thread
From: erik quanstrom @ 2008-02-13 16:37 UTC (permalink / raw)
  To: 9fans

> > ohci.  oddly, my uhci ich9r machine doesn't recognize
> > either of my extensive collection of two usb devices.
>
> You may be running the usbd with faulty dump.c.  If your
> devices show up in /dev/usb0/1/status with just one
> line and 0x000000 for Class/Subclass/Proto, then you're
> almost certainly running the old dump.c.
>
> In dump.c, five lines before the bottom of the file,
> change len = b[0] - 1 into len = b[0]
>
> A new version should already have been posted.
>
> 	Sape

unfortunately, that's not the problem.

- erik


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13 14:45           ` erik quanstrom
  2008-02-13 14:52             ` Richard Miller
@ 2008-02-13 16:18             ` Sape Mullender
  2008-02-13 16:37               ` erik quanstrom
  1 sibling, 1 reply; 29+ messages in thread
From: Sape Mullender @ 2008-02-13 16:18 UTC (permalink / raw)
  To: 9fans

>> Are you killing the old usbd before starting a new one?
>
> yes.
>
>> And is this uhci or ohci?
>
> ohci.  oddly, my uhci ich9r machine doesn't recognize
> either of my extensive collection of two usb devices.

You may be running the usbd with faulty dump.c.  If your
devices show up in /dev/usb0/1/status with just one
line and 0x000000 for Class/Subclass/Proto, then you're
almost certainly running the old dump.c.

In dump.c, five lines before the bottom of the file,
change len = b[0] - 1 into len = b[0]

A new version should already have been posted.

	Sape


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13 14:52             ` Richard Miller
@ 2008-02-13 15:04               ` erik quanstrom
  0 siblings, 0 replies; 29+ messages in thread
From: erik quanstrom @ 2008-02-13 15:04 UTC (permalink / raw)
  To: 9fans

> Sorry, I have no ohci hardware so I don't think I can
> help.  Did the uhci machine recognise your devices
> before the recent update to add ohci support?

just got the machine monday.
i don't think i have any older kernels with usb
compiled in, but i'll see what i can find.

i'd like to rule out bios problem, first.

- erik


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13 14:45           ` erik quanstrom
@ 2008-02-13 14:52             ` Richard Miller
  2008-02-13 15:04               ` erik quanstrom
  2008-02-13 16:18             ` Sape Mullender
  1 sibling, 1 reply; 29+ messages in thread
From: Richard Miller @ 2008-02-13 14:52 UTC (permalink / raw)
  To: 9fans

> ohci.  oddly, my uhci ich9r machine doesn't recognize
> either of my extensive collection of two usb devices.

Sorry, I have no ohci hardware so I don't think I can
help.  Did the uhci machine recognise your devices
before the recent update to add ohci support?


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13 14:32         ` Richard Miller
@ 2008-02-13 14:45           ` erik quanstrom
  2008-02-13 14:52             ` Richard Miller
  2008-02-13 16:18             ` Sape Mullender
  0 siblings, 2 replies; 29+ messages in thread
From: erik quanstrom @ 2008-02-13 14:45 UTC (permalink / raw)
  To: 9fans

> Are you killing the old usbd before starting a new one?

yes.

> And is this uhci or ohci?

ohci.  oddly, my uhci ich9r machine doesn't recognize
either of my extensive collection of two usb devices.

- erik


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-13  0:50       ` erik quanstrom
@ 2008-02-13 14:32         ` Richard Miller
  2008-02-13 14:45           ` erik quanstrom
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Miller @ 2008-02-13 14:32 UTC (permalink / raw)
  To: 9fans

> i've got things pretty wedged now -- usbd won't start

Are you killing the old usbd before starting a new one?

And is this uhci or ohci?


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 14:35     ` Sape Mullender
  2008-02-12 14:42       ` Fco. J. Ballesteros
@ 2008-02-13  0:50       ` erik quanstrom
  2008-02-13 14:32         ` Richard Miller
  1 sibling, 1 reply; 29+ messages in thread
From: erik quanstrom @ 2008-02-13  0:50 UTC (permalink / raw)
  To: 9fans

thanks for the update.  i have switched to a slightly
more agreeable key but i have a new way to fail.  the key
works the first time.  but the second time i connect the same
key, i get

	; usbfat:
	setupreq: write err: No response
	usb/disk: describedevice: error writing usb device request: get device descriptor: No response
	No response
	mount: mount /n/usb: unknown format

initially in this state, i could restart usbd and got this information.

	; usb/usbd -fvD
	usbd: probing usb2/0.1
	usbd: probing usb3/0.1
	usbd: probing usb4/0.1
	usbd: probing usb0/0.1
	out	5	[8] 80 06 00 01 00 00 08 00
	in	5	[8] 12 01 00 02 00 00 00 40
	usb1/0.1 maxpkt: 64
	out	5	[8] 00 05 02 00 00 00 00 00
	describedevice
	out	24	[8] 80 06 00 01 00 00 18 00
	in	24	[18] 12 01 00 02 00 00 00 40 ec 08 08 00 00 01 01 02 03 01
	loadconfig
	out	24	[8] 80 06 00 02 00 00 ff 03
	in	24	[32] 09 02 20 00 01 01 00 80 64 09 04 00 00 02 08 06 50 00 07 05 81 02 40 00 00 07 05 02 02 40 00 00
	out	24	[8] 00 09 01 00 00 00 00 00
	checking usb1/0.1
	...

but two devices (1 and 2) with the identical status files
existed.

i've got things pretty wedged now -- usbd won't start
so it's hard to get much more information. but i did
get two "done > started, 1 0" messages on the console.

sorry for the poor bug report.

- erik


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 14:35     ` Sape Mullender
@ 2008-02-12 14:42       ` Fco. J. Ballesteros
  2008-02-13  0:50       ` erik quanstrom
  1 sibling, 0 replies; 29+ messages in thread
From: Fco. J. Ballesteros @ 2008-02-12 14:42 UTC (permalink / raw)
  To: 9fans

Warning!, the dump.c I sent Sape has a bug.

search for "len = b[0]-1", in pdesc(), replace that with
"len = b[0]".

sorry for the mistake.


>  From: sape@plan9.bell-labs.com
>  To: 9fans@cse.psu.edu
>  Reply-To: 9fans@cse.psu.edu
>  Date: Tue Feb 12 15:36:36 CET 2008
>  Subject: Re: [9fans] usbd problem
>  
>  >> Nemo found a bug in usb/lib/dump.c that may well account for
>  >> this. I incorporated his change (and fixed a bug in his code :-).
>  >> I'll ask Geoff to push it out today.
>  >> 
>  >> 	Sape
>  > 
>  > excellent. i'll give it a shot.
>  > 
>  > - erik
>  
>  Give it a shot now:
>  	/sys/src/cmd/usb/lib/dump.c
>  
>  
>  !— dump.c.txt
>  
>  #include <u.h>
>  #include <libc.h>
>  #include <thread.h>
>  #include <bio.h>
>  #include "usb.h"
>  
>  int verbose;
>  
>  typedef struct Flags Flags;
>  typedef struct Classes Classes;
>  
>  struct Flags {
>  	int	bit;
>  	char*	name0;
>  	char*	name1;
>  };
>  
>  struct Classes {
>  	char*	name;
>  	struct {
>  		char*	name;
>  		char*	proto[4];
>  	} subclass[4];
>  };
>  
>  static Classes	classname[] = {
>  	[CL_AUDIO]	{"audio",	{[1]{"control"}, [2]{"stream"}, [3]{"midi"}}},
>  	[CL_COMMS]	{"comms",	{[1] {"abstract", {[1]"AT"}}}},
>  	[CL_HID]	{"hid",		{[1] {"boot", {[1]"kbd", [2]"mouse"}}}},
>  	[CL_PRINTER]	{"printer",	{[1]"printer", {[1]"uni", [2]"bi"}}},
>  	[CL_HUB]	{"hub",		{[1]{"hub"}}},
>  	[CL_DATA]	{"data"},
>  };
>  
>  static	void	pflag(Flags*, uint);
>  
>  char *
>  sclass(char *p, char *e, ulong csp)
>  {
>  	Classes *cs;
>  	int c, s, pr;
>  
>  	c = Class(csp);
>  	s = Subclass(csp);
>  	pr = Proto(csp);
>  	if(c < 0 || c >= nelem(classname) || (cs = &classname[c])->name == nil)
>  		return seprint(p, e, "%d.%d.%d", c, s, pr);
>  	p = seprint(p, e, "%s.", cs->name);
>  	if(s < 0 || s >= nelem(cs->subclass) || cs->subclass[s].name == nil)
>  		p = seprint(p, e, "%d.%d", s, pr);
>  	else{
>  		p = seprint(p, e, "%s.", cs->subclass[s].name);
>  		if(pr < 0 || pr >= nelem(cs->subclass[s].proto) || cs->subclass[s].proto[pr] == nil)
>  			p = seprint(p, e, "%d", pr);
>  		else
>  			p = seprint(p, e, "%s", cs->subclass[s].proto[pr]);
>  	}
>  	return p;
>  }
>  
>  void
>  pdevice(Device *, int, ulong, void *b, int n)
>  {
>  	DDevice *d;
>  	char scbuf[64];
>  
>  	if(n < DDEVLEN)
>  		return;
>  	d = b;
>  	if(debug & Dbginfo) {
>  		fprint(2, "usb (bcd)%c%c%c%c",
>  				'0'+((d->bcdUSB[1]>>4)&0xf), '0'+(d->bcdUSB[1]&0xf),
>  				'0'+((d->bcdUSB[0]>>4)&0xf), '0'+(d->bcdUSB[0]&0xf));
>  		sclass(scbuf, scbuf + sizeof scbuf,
>  			CSP(d->bDeviceClass, d->bDeviceSubClass, d->bDeviceProtocol)),
>  		fprint(2, " class %d subclass %d proto %d [%s] max0 %d",
>  			d->bDeviceClass, d->bDeviceSubClass, d->bDeviceProtocol,
>  			scbuf,
>  			d->bMaxPacketSize0);
>  		fprint(2, " vendor %#x product %#x device (bcd)%c%c%c%c",
>  			GET2(d->idVendor), GET2(d->idProduct),
>  			'0'+((d->bcdDevice[1]>>4)&0xf), '0'+(d->bcdDevice[1]&0xf),
>  			'0'+((d->bcdDevice[0]>>4)&0xf), '0'+(d->bcdDevice[0]&0xf));
>  		fprint(2, " man %d prod %d serial %d nconfig %d",
>  			d->iManufacturer, d->iProduct, d->iSerialNumber,
>  			d->bNumConfigurations);
>  	}
>  }
>  
>  void
>  phid(Device *, int, ulong, void *b, int n)
>  {
>  	DHid *d;
>  
>  	if(n < DHIDLEN){
>  		fprint(2, "%s: hid too short\n", argv0);
>  		return;
>  	}
>  	d = b;
>  	if(debug & Dbginfo)
>  		fprint(2, "HID (bcd)%c%c%c%c country %d nhidclass %d classdtype %#x dlen %d\n",
>  			'0'+((d->bcdHID[1]>>4)&0xf), '0'+(d->bcdHID[1]&0xf),
>  			'0'+((d->bcdHID[0]>>4)&0xf), '0'+(d->bcdHID[0]&0xf),
>  			d->bCountryCode, d->bNumDescriptors,
>  			d->bClassDescriptorType, GET2(d->wItemLength));
>  }
>  
>  static	Flags	ioflags[] = {
>  	{0, "Data", "Constant"},
>  	{1, "Array", "Variable"},
>  	{2, "Absolute", "Relative"},
>  	{3, "NoWrap", "Wrap"},
>  	{4, "Linear", "NonLinear"},
>  	{5, "PreferredState", "No Preferred State"},
>  	{6, "No Null position", "Null state"},
>  	{7, "Non Volatile", "Volatile"},
>  	{8, "Bit Field", "Buffered Bytes"},
>  	{-1, nil, nil},
>  };
>  
>  static void
>  pflag(Flags *tab, uint v)
>  {
>  	char buf[200], *s;
>  	int n;
>  
>  	n = 0;
>  	buf[0] = 0;
>  	for(; tab->name0 != nil; tab++){
>  		if(v & (1<<tab->bit))
>  			s = tab->name1;
>  		else
>  			s = tab->name0;
>  		if(s != nil && *s)
>  			n += snprint(buf+n, sizeof(buf)-n, ", %s", s);
>  	}
>  	if((debug & Dbginfo) && buf[0])
>  		fprint(2, "[%s]", buf+2);
>  }
>  
>  void
>  preport(Device *, int, ulong, byte *b, int n)
>  {
>  	byte *s, *es;
>  	int tag, nb, i, indent;
>  	int v;
>  	Flags *tab;
>  
>  	s = b+2;
>  	es = b+n;
>  	indent = 0;
>  	while(s < es){
>  		for(i=0; i<indent; i++)
>  			fprint(2, " ");
>  		tag = *s++;
>  		if(tag == Tlong){
>  			fprint(2, "long report tag");
>  			return;
>  		}
>  		if((nb = tag&3) == 3)
>  			nb = 4;
>  		v = 0;
>  		for(i=0; i<nb; i++)
>  			v |= s[i] << (i*8);
>  		switch(tag & Tmtype){
>  		case Treserved:
>  			if(tag == Tlong){
>  				fprint(2, "long report tag");
>  				return;
>  			}
>  			fprint(2, "illegal tag");
>  			return;
>  		case Tmain:
>  			tab = nil;
>  			if (debug & Dbginfo) {
>  				switch(tag & Tmitem){
>  				case Tinput:
>  					fprint(2, "Input");
>  					tab = ioflags;
>  					break;
>  				case Toutput:
>  					fprint(2, "Output");
>  					tab = ioflags;
>  					break;
>  				case Tfeature:
>  					fprint(2, "Feature");
>  					tab = ioflags;
>  					break;
>  				case Tcoll:
>  					fprint(2, "Collection");
>  					indent++;
>  					break;
>  				case Tecoll:
>  					fprint(2, "End Collection");
>  					indent--;
>  					break;
>  				default:
>  					fprint(2, "unexpected item %.2x", tag);
>  				}
>  				fprint(2, "=%#ux", v);
>  				if(tab != nil)
>  					pflag(tab, v);
>  			}
>  			break;
>  		case Tglobal:
>  			if (debug & Dbginfo) {
>  				fprint(2, "Global %#ux: ", v);
>  				switch(tag & Tmitem){
>  				case Tusagepage:
>  					fprint(2, "Usage Page %#ux", v);
>  					break;
>  				case Tlmin:
>  					fprint(2, "Logical Min %d", v);
>  					break;
>  				case Tlmax:
>  					fprint(2, "Logical Max %d", v);
>  					break;
>  				case Tpmin:
>  					fprint(2, "Physical Min %d", v);
>  					break;
>  				case Tpmax:
>  					fprint(2, "Physical Max %d", v);
>  					break;
>  				case Tunitexp:
>  					fprint(2, "Unit Exponent %d", v);
>  					break;
>  				case Tunit:
>  					fprint(2, "Unit %d", v);
>  					break;
>  				case Trepsize:
>  					fprint(2, "Report size %d", v);
>  					break;
>  				case TrepID:
>  					fprint(2, "Report ID %#x", v);
>  					break;
>  				case Trepcount:
>  					fprint(2, "Report Count %d", v);
>  					break;
>  				case Tpush:
>  					fprint(2, "Push %d", v);
>  					break;
>  				case Tpop:
>  					fprint(2, "Pop %d", v);
>  					break;
>  				default:
>  					fprint(2, "Unknown %#ux", v);
>  					break;
>  				}
>  			}
>  			break;
>  		case Tlocal:
>  			if (debug & Dbginfo) {
>  				fprint(2, "Local %#ux: ", v);
>  				switch(tag & Tmitem){
>  				case Tusage:
>  					fprint(2, "Usage %d", v);
>  					break;
>  				case Tumin:
>  					fprint(2, "Usage min %d", v);
>  					break;
>  				case Tumax:
>  					fprint(2, "Usage max %d", v);
>  					break;
>  				case Tdindex:
>  					fprint(2, "Designator index %d", v);
>  					break;
>  				case Tdmin:
>  					fprint(2, "Designator min %d", v);
>  					break;
>  				case Tdmax:
>  					fprint(2, "Designator max %d", v);
>  					break;
>  				case Tsindex:
>  					fprint(2, "String index %d", v);
>  					break;
>  				case Tsmin:
>  					fprint(2, "String min %d", v);
>  					break;
>  				case Tsmax:
>  					fprint(2, "String max %d", v);
>  					break;
>  				case Tsetdelim:
>  					fprint(2, "Set delim %#ux", v);
>  					break;
>  				default:
>  					fprint(2, "Unknown %#ux", v);
>  					break;
>  				}
>  			}
>  			break;
>  		}
>  		fprint(2, "\n");
>  		s += nb;
>  	}
>  }
>  
>  void
>  phub(Device *, int, ulong, void *b, int n)
>  {
>  	DHub *d;
>  
>  	if(n < DHUBLEN)
>  		return;
>  	d = b;
>  	if (debug & Dbginfo)
>  		fprint(2, "nport %d charac %#.4x pwr %dms current %dmA remov %#.2x",
>  			d->bNbrPorts, GET2(d->wHubCharacteristics),
>  			d->bPwrOn2PwrGood*2, d->bHubContrCurrent,
>  			d->DeviceRemovable[0]);
>  }
>  
>  void
>  pstring(Device *, int, ulong, void *b, int n)
>  {
>  	byte *rb;
>  	char *s;
>  	Rune r;
>  	int l;
>  
>  	if(n <= 2){
>  		fprint(2, "\"\"");
>  		return;
>  	}
>  	if(n & 1){
>  		fprint(2, "illegal count\n");
>  		return;
>  	}
>  	n = (n - 2)/2;
>  	rb = (byte*)b + 2;
>  	s = malloc(n*UTFmax+1);
>  	for(l=0; --n >= 0; rb += 2){
>  		r = GET2(rb);
>  		l += runetochar(s+l, &r);
>  	}
>  	s[l] = 0;
>  	fprint(2, "\"%s\"", s);
>  	free(s);
>  }
>  
>  void
>  pcs_raw(char *tag, byte *b, int n)
>  {
>  	int i;
>  
>  	if (debug & Dbginfo) {
>  		fprint(2, "%s", tag);
>  		for(i=2; i<n; i++)
>  			fprint(2, " %.2x", b[i]);
>  	}
>  }
>  
>  static void
>  pcs_config(Device *, int, ulong, void *b, int n)
>  {
>  	pcs_raw("CS_CONFIG", b, n);
>  }
>  
>  static void
>  pcs_string(Device *, ulong, void *b, int n)
>  {
>  	pcs_raw("CS_STRING", b, n);
>  }
>  
>  static void
>  pcs_endpoint(Device *, int, ulong, void *bb, int n)
>  {
>  	byte *b = bb;
>  
>  	if (debug & Dbginfo) {
>  		switch(b[2]) {
>  		case 0x01:
>  			fprint(2,
>  		"CS_ENDPOINT for TerminalID %d, delay %d, format_tag %#ux\n",
>  				b[3], b[4], b[5] | (b[6]<<8));
>  			break;
>  		case 0x02:
>  			fprint(2,
>  "CS_INTERFACE FORMAT_TYPE %d, channels %d, subframesize %d, resolution %d, freqtype %d, ",
>  				b[3], b[4], b[5], b[6], b[7]);
>  			fprint(2, "freq0 %d, freq1 %d\n",
>  				b[8] | b[9]<<8 | b[10]<<16,
>  				b[11] | b[12]<<8 | b[13]<<16);
>  			break;
>  		default:
>  			pcs_raw("CS_INTERFACE", bb, n);
>  		}
>  	}
>  }
>  
>  static void
>  pcs_interface(Device *, int n, ulong, void *bb, int nb)
>  {
>  
>  	if ((debug & Dbginfo) && n >= 0)
>  		pcs_raw("CS_INTERFACE", bb, nb);
>  }
>  
>  void
>  pdesc(Device *d, int c, ulong csp, byte *b, int n)
>  {
>  	int class, subclass, proto, dalt, i, ep, ifc, len;
>  	DConfig *dc;
>  	DEndpoint *de;
>  	DInterface *di;
>  	Dinf *dif;
>  	Endpt *dep;
>  	void (*f)(Device *, int, ulong, void*, int);
>  	char scbuf[64];
>  
>  	class = Class(csp);
>  	dalt = -1;
>  	ifc = -1;
>  	if (c >= nelem(d->config)) {
>  		fprint(2, "Too many interfaces (%d of %d)\n",
>  			c, nelem(d->config));
>  		return;
>  	}
>  	if(debug & Dbginfo)
>  		fprint(2, "pdesc %d.%d [%d]\n", d->id, c, n);
>  	len = -1;
>  	while(n > 2 && b[0] && b[0] <= n){
>  		if (debug & Dbginfo)
>  			fprint(2, "desc %d.%d [%d] %#2.2x: ", d->id, c, b[0], b[1]);
>  		switch (b[1]) {
>  		case CONFIGURATION:
>  			if(b[0] < DCONFLEN){
>  				if(debug & Dbginfo)
>  					fprint(2, "short config %d < %d", b[0], DCONFLEN);
>  				return;
>  			}
>  			dc = (DConfig*)b;
>  			d->config[c]->nif = dc->bNumInterfaces;
>  			d->config[c]->cval = dc->bConfigurationValue;
>  			d->config[c]->attrib = dc->bmAttributes;
>  			d->config[c]->milliamps = dc->MaxPower*2;
>  			d->nif += d->config[c]->nif;
>  			if (debug & Dbginfo)
>  				fprint(2, "config %d: tdlen %d ninterface %d iconfig %d attr %#.2x power %dmA\n",
>  					dc->bConfigurationValue,
>  					GET2(dc->wTotalLength),
>  					dc->bNumInterfaces, dc->iConfiguration,
>  					dc->bmAttributes, dc->MaxPower*2);
>  			break;
>  		case INTERFACE:
>  			if(n < DINTERLEN){
>  				if(debug & Dbginfo)
>  					fprint(2, "short interface %d < %d", b[0], DINTERLEN);
>  				return;
>  			}
>  			di = (DInterface *)b;
>  			class = di->bInterfaceClass;
>  			subclass = di->bInterfaceSubClass;
>  			proto = di->bInterfaceProtocol;
>  			csp = CSP(class, subclass, proto);
>  			if(debug & Dbginfo){
>  				sclass(scbuf, scbuf + sizeof scbuf, csp);
>  				fprint(2, "interface %d: alt %d nept %d class %#x subclass %#x proto %d [%s] iinterface %d\n",
>  					di->bInterfaceNumber,
>  					di->bAlternateSetting,
>  					di->bNumEndpoints, class, subclass,
>  					proto, scbuf, di->iInterface);
>  			}
>  			if (c < 0) {
>  				fprint(2, "Unexpected INTERFACE message\n");
>  				return;
>  			}
>  			ifc = di->bInterfaceNumber;
>  			dalt = di->bAlternateSetting;
>  			if (ifc < 0 || ifc >= nelem(d->config[c]->iface))
>  				sysfatal("Bad interface number %d", ifc);
>  			if (dalt < 0 ||
>  			 dalt >= nelem(d->config[c]->iface[ifc]->dalt))
>  				sysfatal("Bad alternate number %d", dalt);
>  			if (d->config[c] == nil)
>  				sysfatal("No config");
>  			if (ifc == 0) {
>  				if (c == 0)
>  					d->ep[0]->csp = csp;
>  				d->config[c]->csp = csp;
>  			}
>  			dif = d->config[c]->iface[ifc];
>  			if (dif == nil) {
>  				d->config[c]->iface[ifc] = dif =
>  					mallocz(sizeof(Dinf), 1);
>  				dif->csp = csp;
>  			}
>  			dif->interface = di->bInterfaceNumber;
>  			break;
>  		case ENDPOINT:
>  			if(n < DENDPLEN)
>  				return;
>  			de = (DEndpoint *)b;
>  			if(debug & Dbginfo) {
>  				fprint(2, "addr %#2.2x attrib %#2.2x maxpkt %d interval %dms",
>  					de->bEndpointAddress, de->bmAttributes,
>  					GET2(de->wMaxPacketSize), de->bInterval);
>  				if(de->bEndpointAddress & 0x80)
>  					fprint(2, " [IN]");
>  				else
>  					fprint(2, " [OUT]");
>  				switch(de->bmAttributes&0x33){
>  				case 0:
>  					fprint(2, " [Control]");
>  					break;
>  				case 1:
>  					fprint(2, " [Iso]");
>  					switch(de->bmAttributes&0xc){
>  					case 0x4:
>  						fprint(2, " [Asynchronous]");
>  						break;
>  					case 0x8:
>  						fprint(2, " [Adaptive]");
>  						break;
>  					case 0xc:
>  						fprint(2, " [Synchronous]");
>  						break;
>  					}
>  					break;
>  				case 2:
>  					fprint(2, " [Bulk]");
>  					break;
>  				case 3:
>  					fprint(2, " [Interrupt]");
>  					break;
>  				}
>  				if(b[0] == 9)
>  					fprint(2, "refresh %d synchaddress %d",
>  						b[7], b[8]);
>  				fprint(2, "\n");
>  			}
>  			if (c < 0 || ifc < 0 || dalt < 0) {
>  				fprint(2, "Unexpected ENDPOINT message\n");
>  				return;
>  			}
>  			dif = d->config[c]->iface[ifc];
>  			if (dif == nil)
>  				sysfatal("d->config[%d]->iface[%d] == nil",
>  					c, ifc);
>  			if (dif->dalt[dalt] == nil)
>  				dif->dalt[dalt] = mallocz(sizeof(Dalt),1);
>  			dif->dalt[dalt]->attrib = de->bmAttributes;
>  			dif->dalt[dalt]->interval = de->bInterval;
>  			ep = de->bEndpointAddress & 0xf;
>  			dep = d->ep[ep];
>  			if(debug)
>  				fprint(2, "%s: endpoint addr %d\n", argv0, ep);
>  			if(dep == nil){
>  				d->ep[ep] = dep = newendpt(d, ep, class);
>  				dep->dir = de->bEndpointAddress & 0x80
>  					? Ein : Eout;
>  			}else if ((dep->addr&0x80) !=
>  			 (de->bEndpointAddress&0x80))
>  				dep->dir = Eboth;
>  			dep->maxpkt = GET2(de->wMaxPacketSize);
>  			dep->addr = de->bEndpointAddress;
>  			dep->type = de->bmAttributes & 0x03;
>  			dep->isotype = (de->bmAttributes>>2) & 0x03;
>  			dep->csp = csp;
>  			dep->conf = d->config[c];
>  			dep->iface = dif;
>  			for(i = 0; i < nelem(dif->endpt); i++)
>  				if(dif->endpt[i] == nil){
>  					dif->endpt[i] = dep;
>  					break;
>  				}
>  			if(i == nelem(dif->endpt))
>  				fprint(2, "Too many endpoints\n");
>  			if (d->nif <= ep)
>  				d->nif = ep+1;
>  			break;
>  		default:
>  			assert(nelem(dprinter) == 0x100);
>  			f = dprinter[b[1]];
>  			if(f != nil){
>  				(*f)(d, c, dalt<<24 | ifc<<16 | (csp&0xffff),
>  					b, b[0]);
>  				if(debug & Dbginfo)
>  					fprint(2, "\n");
>  			}else
>  				if(verbose){
>  					int i;
>  
>  					switch(b[1]){
>  					case DEVICE:
>  						fprint(2, "(device)");
>  						break;
>  					case STRING:
>  						fprint(2, "(string)");
>  						break;
>  					default:
>  						fprint(2, "(unknown type)");
>  					}
>  					for(i=1; i<b[0]; i++)
>  						fprint(2, " %.2x", b[i]);
>  					fprint(2, "\n");
>  				}else if(debug & Dbginfo)
>  					fprint(2, "\n");
>  			break;
>  		}
>  		len = b[0];
>  		n -= len;
>  		b += len;
>  	}
>  	if(n)
>  		fprint(2, "pdesc: %d bytes left unparsed, b[0]=%d, b[-len]=%d, len=%d\n", n, b[0], b[-len], len);	
>  }


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 14:13   ` erik quanstrom
@ 2008-02-12 14:35     ` Sape Mullender
  2008-02-12 14:42       ` Fco. J. Ballesteros
  2008-02-13  0:50       ` erik quanstrom
  0 siblings, 2 replies; 29+ messages in thread
From: Sape Mullender @ 2008-02-12 14:35 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 296 bytes --]

>> Nemo found a bug in usb/lib/dump.c that may well account for
>> this.  I incorporated his change (and fixed a bug in his code :-).
>> I'll ask Geoff to push it out today.
>>
>> 	Sape
>
> excellent.  i'll give it a shot.
>
> - erik

Give it a shot now:
	/sys/src/cmd/usb/lib/dump.c

[-- Attachment #2: dump.c --]
[-- Type: text/plain, Size: 14184 bytes --]

#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include "usb.h"

int verbose;

typedef struct Flags Flags;
typedef struct Classes Classes;

struct Flags {
	int	bit;
	char*	name0;
	char*	name1;
};

struct Classes {
	char*	name;
	struct {
		char*	name;
		char*	proto[4];
	} subclass[4];
};

static Classes	classname[] = {
	[CL_AUDIO]	{"audio",	{[1]{"control"}, [2]{"stream"}, [3]{"midi"}}},
	[CL_COMMS]	{"comms",	{[1] {"abstract", {[1]"AT"}}}},
	[CL_HID]	{"hid",		{[1] {"boot", {[1]"kbd", [2]"mouse"}}}},
	[CL_PRINTER]	{"printer",	{[1]"printer", {[1]"uni", [2]"bi"}}},
	[CL_HUB]	{"hub",		{[1]{"hub"}}},
	[CL_DATA]	{"data"},
};

static	void	pflag(Flags*, uint);

char *
sclass(char *p, char *e, ulong csp)
{
	Classes *cs;
	int c, s, pr;

	c = Class(csp);
	s = Subclass(csp);
	pr = Proto(csp);
	if(c < 0 || c >= nelem(classname) || (cs = &classname[c])->name == nil)
		return seprint(p, e, "%d.%d.%d", c, s, pr);
	p = seprint(p, e, "%s.", cs->name);
	if(s < 0 || s >= nelem(cs->subclass) || cs->subclass[s].name == nil)
		p = seprint(p, e, "%d.%d", s, pr);
	else{
		p = seprint(p, e, "%s.", cs->subclass[s].name);
		if(pr < 0 || pr >= nelem(cs->subclass[s].proto) || cs->subclass[s].proto[pr] == nil)
			p = seprint(p, e, "%d", pr);
		else
			p = seprint(p, e, "%s", cs->subclass[s].proto[pr]);
	}
	return p;
}

void
pdevice(Device *, int, ulong, void *b, int n)
{
	DDevice *d;
	char scbuf[64];

	if(n < DDEVLEN)
		return;
	d = b;
	if(debug & Dbginfo) {
		fprint(2, "usb (bcd)%c%c%c%c",
				'0'+((d->bcdUSB[1]>>4)&0xf), '0'+(d->bcdUSB[1]&0xf),
				'0'+((d->bcdUSB[0]>>4)&0xf), '0'+(d->bcdUSB[0]&0xf));
		sclass(scbuf, scbuf + sizeof scbuf,
			CSP(d->bDeviceClass, d->bDeviceSubClass, d->bDeviceProtocol)),
		fprint(2, " class %d subclass %d proto %d [%s] max0 %d",
			d->bDeviceClass, d->bDeviceSubClass, d->bDeviceProtocol,
			scbuf,
			d->bMaxPacketSize0);
		fprint(2, " vendor %#x product %#x device (bcd)%c%c%c%c",
			GET2(d->idVendor), GET2(d->idProduct),
			'0'+((d->bcdDevice[1]>>4)&0xf), '0'+(d->bcdDevice[1]&0xf),
			'0'+((d->bcdDevice[0]>>4)&0xf), '0'+(d->bcdDevice[0]&0xf));
		fprint(2, " man %d prod %d serial %d nconfig %d",
			d->iManufacturer, d->iProduct, d->iSerialNumber,
			d->bNumConfigurations);
	}
}

void
phid(Device *, int, ulong, void *b, int n)
{
	DHid *d;

	if(n < DHIDLEN){
		fprint(2, "%s: hid too short\n", argv0);
		return;
	}
	d = b;
	if(debug & Dbginfo)
		fprint(2, "HID (bcd)%c%c%c%c country %d nhidclass %d classdtype %#x dlen %d\n",
			'0'+((d->bcdHID[1]>>4)&0xf), '0'+(d->bcdHID[1]&0xf),
			'0'+((d->bcdHID[0]>>4)&0xf), '0'+(d->bcdHID[0]&0xf),
			d->bCountryCode, d->bNumDescriptors,
			d->bClassDescriptorType, GET2(d->wItemLength));
}

static	Flags	ioflags[] = {
	{0, "Data", "Constant"},
	{1, "Array", "Variable"},
	{2, "Absolute", "Relative"},
	{3, "NoWrap", "Wrap"},
	{4, "Linear", "NonLinear"},
	{5, "PreferredState", "No Preferred State"},
	{6, "No Null position", "Null state"},
	{7, "Non Volatile", "Volatile"},
	{8, "Bit Field", "Buffered Bytes"},
	{-1, nil, nil},
};

static void
pflag(Flags *tab, uint v)
{
	char buf[200], *s;
	int n;

	n = 0;
	buf[0] = 0;
	for(; tab->name0 != nil; tab++){
		if(v & (1<<tab->bit))
			s = tab->name1;
		else
			s = tab->name0;
		if(s != nil && *s)
			n += snprint(buf+n, sizeof(buf)-n, ", %s", s);
	}
	if((debug & Dbginfo) && buf[0])
		fprint(2, "[%s]", buf+2);
}

void
preport(Device *, int, ulong, byte *b, int n)
{
	byte *s, *es;
	int tag, nb, i, indent;
	int v;
	Flags *tab;

	s = b+2;
	es = b+n;
	indent = 0;
	while(s < es){
		for(i=0; i<indent; i++)
			fprint(2, " ");
		tag = *s++;
		if(tag == Tlong){
			fprint(2, "long report tag");
			return;
		}
		if((nb = tag&3) == 3)
			nb = 4;
		v = 0;
		for(i=0; i<nb; i++)
			v |= s[i] << (i*8);
		switch(tag & Tmtype){
		case Treserved:
			if(tag == Tlong){
				fprint(2, "long report tag");
				return;
			}
			fprint(2, "illegal tag");
			return;
		case Tmain:
			tab = nil;
			if (debug & Dbginfo) {
				switch(tag & Tmitem){
				case Tinput:
					fprint(2, "Input");
					tab = ioflags;
					break;
				case Toutput:
					fprint(2, "Output");
					tab = ioflags;
					break;
				case Tfeature:
					fprint(2, "Feature");
					tab = ioflags;
					break;
				case Tcoll:
					fprint(2, "Collection");
					indent++;
					break;
				case Tecoll:
					fprint(2, "End Collection");
					indent--;
					break;
				default:
					fprint(2, "unexpected item %.2x", tag);
				}
				fprint(2, "=%#ux", v);
				if(tab != nil)
					pflag(tab, v);
			}
			break;
		case Tglobal:
			if (debug & Dbginfo) {
				fprint(2, "Global %#ux: ", v);
				switch(tag & Tmitem){
				case Tusagepage:
					fprint(2, "Usage Page %#ux", v);
					break;
				case Tlmin:
					fprint(2, "Logical Min %d", v);
					break;
				case Tlmax:
					fprint(2, "Logical Max %d", v);
					break;
				case Tpmin:
					fprint(2, "Physical Min %d", v);
					break;
				case Tpmax:
					fprint(2, "Physical Max %d", v);
					break;
				case Tunitexp:
					fprint(2, "Unit Exponent %d", v);
					break;
				case Tunit:
					fprint(2, "Unit %d", v);
					break;
				case Trepsize:
					fprint(2, "Report size %d", v);
					break;
				case TrepID:
					fprint(2, "Report ID %#x", v);
					break;
				case Trepcount:
					fprint(2, "Report Count %d", v);
					break;
				case Tpush:
					fprint(2, "Push %d", v);
					break;
				case Tpop:
					fprint(2, "Pop %d", v);
					break;
				default:
					fprint(2, "Unknown %#ux", v);
					break;
				}
			}
			break;
		case Tlocal:
			if (debug & Dbginfo) {
				fprint(2, "Local %#ux: ", v);
				switch(tag & Tmitem){
				case Tusage:
					fprint(2, "Usage %d", v);
					break;
				case Tumin:
					fprint(2, "Usage min %d", v);
					break;
				case Tumax:
					fprint(2, "Usage max %d", v);
					break;
				case Tdindex:
					fprint(2, "Designator index %d", v);
					break;
				case Tdmin:
					fprint(2, "Designator min %d", v);
					break;
				case Tdmax:
					fprint(2, "Designator max %d", v);
					break;
				case Tsindex:
					fprint(2, "String index %d", v);
					break;
				case Tsmin:
					fprint(2, "String min %d", v);
					break;
				case Tsmax:
					fprint(2, "String max %d", v);
					break;
				case Tsetdelim:
					fprint(2, "Set delim %#ux", v);
					break;
				default:
					fprint(2, "Unknown %#ux", v);
					break;
				}
			}
			break;
		}
		fprint(2, "\n");
		s += nb;
	}
}

void
phub(Device *, int, ulong, void *b, int n)
{
	DHub *d;

	if(n < DHUBLEN)
		return;
	d = b;
	if (debug & Dbginfo)
		fprint(2, "nport %d charac %#.4x pwr %dms current %dmA remov %#.2x",
			d->bNbrPorts, GET2(d->wHubCharacteristics),
			d->bPwrOn2PwrGood*2, d->bHubContrCurrent,
			d->DeviceRemovable[0]);
}

void
pstring(Device *, int, ulong, void *b, int n)
{
	byte *rb;
	char *s;
	Rune r;
	int l;

	if(n <= 2){
		fprint(2, "\"\"");
		return;
	}
	if(n & 1){
		fprint(2, "illegal count\n");
		return;
	}
	n = (n - 2)/2;
	rb = (byte*)b + 2;
	s = malloc(n*UTFmax+1);
	for(l=0; --n >= 0; rb += 2){
		r = GET2(rb);
		l += runetochar(s+l, &r);
	}
	s[l] = 0;
	fprint(2, "\"%s\"", s);
	free(s);
}

void
pcs_raw(char *tag, byte *b, int n)
{
	int i;

	if (debug & Dbginfo) {
		fprint(2, "%s", tag);
		for(i=2; i<n; i++)
			fprint(2, " %.2x", b[i]);
	}
}

static void
pcs_config(Device *, int, ulong, void *b, int n)
{
	pcs_raw("CS_CONFIG", b, n);
}

static void
pcs_string(Device *, ulong, void *b, int n)
{
	pcs_raw("CS_STRING", b, n);
}

static void
pcs_endpoint(Device *, int, ulong, void *bb, int n)
{
	byte *b = bb;

	if (debug & Dbginfo) {
		switch(b[2]) {
		case 0x01:
			fprint(2,
		"CS_ENDPOINT for TerminalID %d, delay %d, format_tag %#ux\n",
				b[3], b[4], b[5] | (b[6]<<8));
			break;
		case 0x02:
			fprint(2,
"CS_INTERFACE FORMAT_TYPE %d, channels %d, subframesize %d, resolution %d, freqtype %d, ",
				b[3], b[4], b[5], b[6], b[7]);
			fprint(2, "freq0 %d, freq1 %d\n",
				b[8]  |  b[9]<<8 | b[10]<<16,
				b[11] | b[12]<<8 | b[13]<<16);
			break;
		default:
			pcs_raw("CS_INTERFACE", bb, n);
		}
	}
}

static void
pcs_interface(Device *, int n, ulong, void *bb, int nb)
{

	if ((debug & Dbginfo) && n >= 0)
		pcs_raw("CS_INTERFACE", bb, nb);
}

void
pdesc(Device *d, int c, ulong csp, byte *b, int n)
{
	int class, subclass, proto, dalt, i, ep, ifc, len;
	DConfig *dc;
	DEndpoint *de;
	DInterface *di;
	Dinf *dif;
	Endpt *dep;
	void (*f)(Device *, int, ulong, void*, int);
	char scbuf[64];

	class = Class(csp);
	dalt = -1;
	ifc = -1;
	if (c >= nelem(d->config)) {
		fprint(2, "Too many interfaces (%d of %d)\n",
			c, nelem(d->config));
		return;
	}
	if(debug & Dbginfo)
		fprint(2, "pdesc %d.%d [%d]\n", d->id, c, n);
	len = -1;
	while(n > 2 && b[0] && b[0] <= n){
		if (debug & Dbginfo)
			fprint(2, "desc %d.%d [%d] %#2.2x: ", d->id, c, b[0], b[1]);
		switch (b[1]) {
		case CONFIGURATION:
			if(b[0] < DCONFLEN){
				if(debug & Dbginfo)
					fprint(2, "short config %d < %d", b[0], DCONFLEN);
				return;
			}
			dc = (DConfig*)b;
			d->config[c]->nif = dc->bNumInterfaces;
			d->config[c]->cval = dc->bConfigurationValue;
			d->config[c]->attrib = dc->bmAttributes;
			d->config[c]->milliamps = dc->MaxPower*2;
			d->nif += d->config[c]->nif;
			if (debug & Dbginfo)
				fprint(2, "config %d: tdlen %d ninterface %d iconfig %d attr %#.2x power %dmA\n",
					dc->bConfigurationValue,
					GET2(dc->wTotalLength),
					dc->bNumInterfaces, dc->iConfiguration,
					dc->bmAttributes, dc->MaxPower*2);
			break;
		case INTERFACE:
			if(n < DINTERLEN){
				if(debug & Dbginfo)
					fprint(2, "short interface %d < %d", b[0], DINTERLEN);
				return;
			}
			di = (DInterface *)b;
			class = di->bInterfaceClass;
			subclass = di->bInterfaceSubClass;
			proto = di->bInterfaceProtocol;
			csp = CSP(class, subclass, proto);
			if(debug & Dbginfo){
				sclass(scbuf, scbuf + sizeof scbuf, csp);
				fprint(2, "interface %d: alt %d nept %d class %#x subclass %#x proto %d [%s] iinterface %d\n",
					di->bInterfaceNumber,
					di->bAlternateSetting,
					di->bNumEndpoints, class, subclass,
					proto, scbuf, di->iInterface);
			}
			if (c < 0) {
				fprint(2, "Unexpected INTERFACE message\n");
				return;
			}
			ifc = di->bInterfaceNumber;
			dalt = di->bAlternateSetting;
			if (ifc < 0 || ifc >= nelem(d->config[c]->iface))
				sysfatal("Bad interface number %d", ifc);
			if (dalt < 0 ||
			    dalt >= nelem(d->config[c]->iface[ifc]->dalt))
				sysfatal("Bad alternate number %d", dalt);
			if (d->config[c] == nil)
				sysfatal("No config");
			if (ifc == 0) {
				if (c == 0)
					d->ep[0]->csp = csp;
				d->config[c]->csp = csp;
			}
			dif = d->config[c]->iface[ifc];
			if (dif == nil) {
				d->config[c]->iface[ifc] = dif =
					mallocz(sizeof(Dinf), 1);
				dif->csp = csp;
			}
			dif->interface = di->bInterfaceNumber;
			break;
		case ENDPOINT:
			if(n < DENDPLEN)
				return;
			de = (DEndpoint *)b;
			if(debug & Dbginfo) {
				fprint(2, "addr %#2.2x attrib %#2.2x maxpkt %d interval %dms",
					de->bEndpointAddress, de->bmAttributes,
					GET2(de->wMaxPacketSize), de->bInterval);
				if(de->bEndpointAddress & 0x80)
					fprint(2, " [IN]");
				else
					fprint(2, " [OUT]");
				switch(de->bmAttributes&0x33){
				case 0:
					fprint(2, " [Control]");
					break;
				case 1:
					fprint(2, " [Iso]");
					switch(de->bmAttributes&0xc){
					case 0x4:
						fprint(2, " [Asynchronous]");
						break;
					case 0x8:
						fprint(2, " [Adaptive]");
						break;
					case 0xc:
						fprint(2, " [Synchronous]");
						break;
					}
					break;
				case 2:
					fprint(2, " [Bulk]");
					break;
				case 3:
					fprint(2, " [Interrupt]");
					break;
				}
				if(b[0] == 9)
					fprint(2, "refresh %d synchaddress %d",
						b[7], b[8]);
				fprint(2, "\n");
			}
			if (c < 0 || ifc < 0 || dalt < 0) {
				fprint(2, "Unexpected ENDPOINT message\n");
				return;
			}
			dif = d->config[c]->iface[ifc];
			if (dif == nil)
				sysfatal("d->config[%d]->iface[%d] == nil",
					c, ifc);
			if (dif->dalt[dalt] == nil)
				dif->dalt[dalt] = mallocz(sizeof(Dalt),1);
			dif->dalt[dalt]->attrib = de->bmAttributes;
			dif->dalt[dalt]->interval = de->bInterval;
			ep = de->bEndpointAddress & 0xf;
			dep = d->ep[ep];
			if(debug)
				fprint(2, "%s: endpoint addr %d\n", argv0, ep);
			if(dep == nil){
				d->ep[ep] = dep = newendpt(d, ep, class);
				dep->dir = de->bEndpointAddress & 0x80
					? Ein : Eout;
			}else if ((dep->addr&0x80) !=
			    (de->bEndpointAddress&0x80))
				dep->dir = Eboth;
			dep->maxpkt = GET2(de->wMaxPacketSize);
			dep->addr = de->bEndpointAddress;
			dep->type = de->bmAttributes & 0x03;
			dep->isotype = (de->bmAttributes>>2) & 0x03;
			dep->csp = csp;
			dep->conf = d->config[c];
			dep->iface = dif;
			for(i = 0; i < nelem(dif->endpt); i++)
				if(dif->endpt[i] == nil){
					dif->endpt[i] = dep;
					break;
				}
			if(i == nelem(dif->endpt))
				fprint(2, "Too many endpoints\n");
			if (d->nif <= ep)
				d->nif = ep+1;
			break;
		default:
			assert(nelem(dprinter) == 0x100);
			f = dprinter[b[1]];
			if(f != nil){
				(*f)(d, c, dalt<<24 | ifc<<16 | (csp&0xffff),
					b, b[0]);
				if(debug & Dbginfo)
					fprint(2, "\n");
			}else
				if(verbose){
					int i;

					switch(b[1]){
					case DEVICE:
						fprint(2, "(device)");
						break;
					case STRING:
						fprint(2, "(string)");
						break;
					default:
						fprint(2, "(unknown type)");
					}
					for(i=1; i<b[0]; i++)
						fprint(2, " %.2x", b[i]);
					fprint(2, "\n");
				}else if(debug & Dbginfo)
					fprint(2, "\n");
			break;
		}
		len = b[0];
		n -= len;
		b += len;
	}
	if(n)
		fprint(2, "pdesc: %d bytes left unparsed, b[0]=%d, b[-len]=%d, len=%d\n", n, b[0], b[-len], len);
}

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12 13:59 ` Sape Mullender
@ 2008-02-12 14:13   ` erik quanstrom
  2008-02-12 14:35     ` Sape Mullender
  0 siblings, 1 reply; 29+ messages in thread
From: erik quanstrom @ 2008-02-12 14:13 UTC (permalink / raw)
  To: 9fans

> Nemo found a bug in usb/lib/dump.c that may well account for
> this.  I incorporated his change (and fixed a bug in his code :-).
> I'll ask Geoff to push it out today.
>
> 	Sape

excellent.  i'll give it a shot.

- erik


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12  1:36 erik quanstrom
  2008-02-12  8:20 ` Richard Miller
@ 2008-02-12 13:59 ` Sape Mullender
  2008-02-12 14:13   ` erik quanstrom
  1 sibling, 1 reply; 29+ messages in thread
From: Sape Mullender @ 2008-02-12 13:59 UTC (permalink / raw)
  To: 9fans

> usbd is exiting when i have a camera which is off
> attached:
>
> ; usb/usbd -v
> ; echo $status
> usbd 1827: usbd: setup0: usb0/1: transaction error
>
> - erik

Nemo found a bug in usb/lib/dump.c that may well account for
this.  I incorporated his change (and fixed a bug in his code :-).
I'll ask Geoff to push it out today.

	Sape


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [9fans] usbd problem
  2008-02-12  1:36 erik quanstrom
@ 2008-02-12  8:20 ` Richard Miller
  2008-02-12 13:59 ` Sape Mullender
  1 sibling, 0 replies; 29+ messages in thread
From: Richard Miller @ 2008-02-12  8:20 UTC (permalink / raw)
  To: 9fans

> ; usb/usbd -v

Try 'usb/usbd -d1' for more information.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [9fans] usbd problem
@ 2008-02-12  1:36 erik quanstrom
  2008-02-12  8:20 ` Richard Miller
  2008-02-12 13:59 ` Sape Mullender
  0 siblings, 2 replies; 29+ messages in thread
From: erik quanstrom @ 2008-02-12  1:36 UTC (permalink / raw)
  To: 9fans

usbd is exiting when i have a camera which is off
attached:

; usb/usbd -v
; echo $status
usbd 1827: usbd: setup0: usb0/1: transaction error

- erik


^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2008-02-13 18:49 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-12  8:21 [9fans] usbd problem Richard Miller
2008-02-12 13:21 ` erik quanstrom
2008-02-12 21:24   ` Richard Miller
2008-02-12 21:28     ` geoff
2008-02-12 21:33       ` Richard Miller
2008-02-12 21:37     ` erik quanstrom
2008-02-12 22:18       ` Richard Miller
2008-02-12 23:05         ` geoff
2008-02-13  6:31           ` arisawa
2008-02-13  8:25             ` Richard Miller
2008-02-13  8:54               ` arisawa
2008-02-13 10:58             ` Richard Miller
2008-02-13 14:13               ` Richard Miller
2008-02-13 18:49                 ` geoff
2008-02-13 15:54           ` Richard Miller
  -- strict thread matches above, loose matches on Subject: below --
2008-02-12  1:36 erik quanstrom
2008-02-12  8:20 ` Richard Miller
2008-02-12 13:59 ` Sape Mullender
2008-02-12 14:13   ` erik quanstrom
2008-02-12 14:35     ` Sape Mullender
2008-02-12 14:42       ` Fco. J. Ballesteros
2008-02-13  0:50       ` erik quanstrom
2008-02-13 14:32         ` Richard Miller
2008-02-13 14:45           ` erik quanstrom
2008-02-13 14:52             ` Richard Miller
2008-02-13 15:04               ` erik quanstrom
2008-02-13 16:18             ` Sape Mullender
2008-02-13 16:37               ` erik quanstrom
2008-02-13 17:09                 ` Sape Mullender

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).