Re: fun with ktrace, gdb, usb devices, and umsm(4)

2008-05-13 Thread Stuart Henderson
On 2008-05-13, Aaron Glenn [EMAIL PROTECTED] wrote:
 I'm trying to get my Sierra Wireless MC5720 modem to work and I'm not
 having much luck.

I don't know if this is useful or a red herring, but when this id was
added to Linux, they also added code which ensures that the device
is turned on when inserted into the system. They use it for all
devices supported by the driver, they don't match to any particular
device. http://lkml.org/lkml/2007/1/17/188

Looking at usb_control_msg details on http://tinyurl.com/539896 and
this from the above diff:

+   __u16 set_mode_dzero = 0x;
...
+   /*set mode to D0 */
+   result = usb_control_msg(serial-dev,
+   usb_rcvctrlpipe(serial-dev, 0),
+   0x00,0x40,set_mode_dzero,0,NULL,0,USB_CTRL_SET_TIMEOUT);
  `value---' | `data
request- -request type   `index

I baked the somewhat random diff below, if it doesn't help I don't
know where else to look, and if it does help count me quite surprised!
It does at least compile :)

 In a vain attempt to school myself, I've tried to ktrace and gdb my
 way into figuring out why I can't get this card to work. Doing a cu
 -l /dev/cuaU0 -swhatever ends in a hard lock.

I am no kernel wizard but if it's hanging in the kernel, that
behaviour seems reasonable. There are other ways, but the simplest
is probably to sprinkle some printf..


Index: umsm.c
===
RCS file: /cvs/src/sys/dev/usb/umsm.c,v
retrieving revision 1.25
diff -u -p -r1.25 umsm.c
--- umsm.c  12 May 2008 12:24:43 -  1.25
+++ umsm.c  13 May 2008 12:15:04 -
@@ -45,11 +45,14 @@ int umsmdebug = 1;
 
 #define DPRINTF(x) DPRINTFN(0, x)
 
-
 #define UMSMBUFSZ  4096
 #defineUMSM_INTR_INTERVAL  100 /* ms */
+
 #define E220_MODE_CHANGE_REQUEST 0x2
 
+#define UMSM_SET_POWER_REQUEST 0x0
+#define UMSM_POWER_MODE_D0 0x
+
 int umsm_match(struct device *, void *, void *); 
 void umsm_attach(struct device *, struct device *, void *); 
 int umsm_detach(struct device *, int); 
@@ -61,6 +64,7 @@ void umsm_intr(usbd_xfer_handle, usbd_pr
 void umsm_get_status(void *, int, u_char *, u_char *);
 
 usbd_status umsm_e220_changemode(usbd_device_handle);
+usbd_status umsm_set_power_dzero(usbd_device_handle);
 
 struct umsm_softc {
struct devicesc_dev;
@@ -180,6 +184,7 @@ umsm_attach(struct device *parent, struc
sc-sc_udev = uaa-device;
sc-sc_iface = uaa-iface;
 
+   umsm_set_power_dzero(uaa-device);
id = usbd_get_interface_descriptor(sc-sc_iface);
 
if (id == NULL || id-bInterfaceClass == UICLASS_MASS) {
@@ -391,6 +396,25 @@ umsm_e220_changemode(usbd_device_handle 
 
err = usbd_do_request(dev, req, 0);
if (err) 
+   return (EIO);
+
+   return (0);
+}
+
+usbd_status
+umsm_set_power_dzero(usbd_device_handle dev)
+{
+   usb_device_request_t req;
+   usbd_status err;
+
+   req.bmRequestType = UT_VENDOR;
+   req.bRequest = UMSM_SET_POWER_REQUEST;
+   USETW(req.wValue, UMSM_POWER_MODE_D0);
+   USETW(req.wIndex, 0);
+   USETW(req.wLength, 0);
+
+   err = usbd_do_request(dev, req, 0);
+   if (err)
return (EIO);
 
return (0);



Re: fun with ktrace, gdb, usb devices, and umsm(4)

2008-05-13 Thread Aaron Glenn
On Tue, May 13, 2008 at 5:56 AM, Stuart Henderson [EMAIL PROTECTED] wrote:

  I don't know if this is useful or a red herring, but when this id was
  added to Linux, they also added code which ensures that the device
  is turned on when inserted into the system. They use it for all
  devices supported by the driver, they don't match to any particular
  device. http://lkml.org/lkml/2007/1/17/188

  Looking at usb_control_msg details on http://tinyurl.com/539896 and
  this from the above diff:

  +   __u16 set_mode_dzero = 0x;
  ...
  +   /*set mode to D0 */
  +   result = usb_control_msg(serial-dev,
  +   usb_rcvctrlpipe(serial-dev, 0),
  +   
 0x00,0x40,set_mode_dzero,0,NULL,0,USB_CTRL_SET_TIMEOUT);
   `value---' | `data
 request- -request type   `index

  I baked the somewhat random diff below, if it doesn't help I don't
  know where else to look, and if it does help count me quite surprised!
  It does at least compile :)

It might? I'm not quite sure how it works (haha, there's the first
problem, right?); however it is embedded in the machine...however it
does need to be turned on. At least, thats how the VZAccess Manager
software in Windows works (the power light for the modem is off when
disconnected). I'll definitely try it out.


   In a vain attempt to school myself, I've tried to ktrace and gdb my
   way into figuring out why I can't get this card to work. Doing a cu
   -l /dev/cuaU0 -swhatever ends in a hard lock.

  I am no kernel wizard but if it's hanging in the kernel, that
  behaviour seems reasonable. There are other ways, but the simplest
  is probably to sprinkle some printf..

Well that's my ultimate question -- how do I debug this? And in this
case, if it is a sprinkling of printf, where do they go? I'm trying to
do this with as minimal hand holding as possible -- really want to
learn this stuff. I can only read usb(4) so many times.


  Index: umsm.c
  ===
  RCS file: /cvs/src/sys/dev/usb/umsm.c,v
  retrieving revision 1.25
  diff -u -p -r1.25 umsm.c
  --- umsm.c  12 May 2008 12:24:43 -  1.25
  +++ umsm.c  13 May 2008 12:15:04 -
  @@ -45,11 +45,14 @@ int umsmdebug = 1;

   #define DPRINTF(x) DPRINTFN(0, x)

  -
   #define UMSMBUFSZ  4096
   #defineUMSM_INTR_INTERVAL  100 /* ms */
  +
   #define E220_MODE_CHANGE_REQUEST 0x2

  +#define UMSM_SET_POWER_REQUEST 0x0
  +#define UMSM_POWER_MODE_D0 0x
  +
   int umsm_match(struct device *, void *, void *);
   void umsm_attach(struct device *, struct device *, void *);
   int umsm_detach(struct device *, int);
  @@ -61,6 +64,7 @@ void umsm_intr(usbd_xfer_handle, usbd_pr
   void umsm_get_status(void *, int, u_char *, u_char *);

   usbd_status umsm_e220_changemode(usbd_device_handle);
  +usbd_status umsm_set_power_dzero(usbd_device_handle);

   struct umsm_softc {
 struct devicesc_dev;
  @@ -180,6 +184,7 @@ umsm_attach(struct device *parent, struc
 sc-sc_udev = uaa-device;
 sc-sc_iface = uaa-iface;

  +   umsm_set_power_dzero(uaa-device);
 id = usbd_get_interface_descriptor(sc-sc_iface);

 if (id == NULL || id-bInterfaceClass == UICLASS_MASS) {
  @@ -391,6 +396,25 @@ umsm_e220_changemode(usbd_device_handle

 err = usbd_do_request(dev, req, 0);
 if (err)
  +   return (EIO);
  +
  +   return (0);
  +}
  +
  +usbd_status
  +umsm_set_power_dzero(usbd_device_handle dev)
  +{
  +   usb_device_request_t req;
  +   usbd_status err;
  +
  +   req.bmRequestType = UT_VENDOR;
  +   req.bRequest = UMSM_SET_POWER_REQUEST;
  +   USETW(req.wValue, UMSM_POWER_MODE_D0);
  +   USETW(req.wIndex, 0);
  +   USETW(req.wLength, 0);
  +
  +   err = usbd_do_request(dev, req, 0);
  +   if (err)
 return (EIO);

 return (0);

Appreciate it -- I'll try it out.


aaron.glenn