Re: PROBLEM : Device Re-enumeration not happening after reset
"Jithu Joseph" <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
Dear Alan, Oliver and others,
Thanks really for pointing out, "Reenumeration after a reset wasn't
implemented in 2.4! It's present only in the 2.6 kernel".
Yesterday i compared my 2.4.27 with 2.6.22 and found out that the
re-enumerate stuff as mentioned by Oliver is missing in 2.4.27's
usb_reset_device () function.
Are you aware of any functions in 2.4 kernel which can be used within
a kernel level usb client driver which will trigger a re-enumeration
of the device. Then i can issue that call after the reset call .
[Since i am working with an embedded board - i am not in a position to
port the kernel to a 2.6 version] . Even some calls to re-enumerate
the entire usb tree should do -as this is my only device.
I assume that if there is no way to trigger a renumeration from within
the kernel level driver then i will have to make some changes to
hub.c's usb_reset_device () , - or are there any easier or simpler
ways to attain my objective. Replugging the device is not an option
for me.
Perhaps i can attempt something like - instead of trying to load a
different DFU driver after the reset - i can bring DFU logic within
this driver, issue a reset - then set configuration etc and proceed
with the download
Being relatively new to kernel development and being my first post to
the group - i am really bowled over by your responses and supporting
nature - Once again a big thanks - frankly i never expected a
response.
Thanks and Regards
Jithu Joseph
// I am just copying the 2.4.27's hub.c's usb_reset_device () device -
just in case some of you might want to take a quick glance
int usb_reset_device(struct usb_device *dev)
{
struct usb_device *parent = dev->parent;
struct usb_device_descriptor *descriptor;
int i, ret, port = -1;
if (!parent) {
err("attempting to reset root hub!");
return -EINVAL;
}
for (i = 0; i < parent->maxchild; i++)
if (parent->children[i] == dev) {
port = i;
break;
}
if (port < 0)
return -ENOENT;
down(&usb_address0_sem);
/* Send a reset to the device */
if (usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
usb_hub_port_disable(parent, port);
up(&usb_address0_sem);
return(-ENODEV);
}
/* Reprogram the Address */
ret = usb_set_address(dev);
if (ret < 0) {
err("USB device not accepting new address (error=%d)", ret);
usb_hub_port_disable(parent, port);
up(&usb_address0_sem);
return ret;
}
/* Let the SET_ADDRESS settle */
wait_ms(10);
up(&usb_address0_sem);
/*
* Now we fetch the configuration descriptors for the device and
* see if anything has changed. If it has, we dump the current
* parsed descriptors and reparse from scratch. Then we leave
* the device alone for the caller to finish setting up.
*
* If nothing changed, we reprogram the configuration and then
* the alternate settings.
*/
descriptor = kmalloc(sizeof *descriptor, GFP_NOIO);
if (!descriptor) {
return -ENOMEM;
}
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, descriptor,
sizeof(*descriptor));
if (ret < 0) {
kfree(descriptor);
return ret;
}
le16_to_cpus(&descriptor->bcdUSB);
le16_to_cpus(&descriptor->idVendor);
le16_to_cpus(&descriptor->idProduct);
le16_to_cpus(&descriptor->bcdDevice);
if (memcmp(&dev->descriptor, descriptor, sizeof(*descriptor))) {
kfree(descriptor);
usb_destroy_configuration(dev);
ret = usb_get_device_descriptor(dev);
if (ret < sizeof(dev->descriptor)) {
if (ret < 0)
err("unable to get device descriptor (error=%d)", ret);
else
err("USB device descriptor short read (expected %Zi, got %i)",
sizeof(dev->descriptor), ret);
clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
dev->devnum = -1;
return -EIO;
}
ret = usb_get_configuration(dev);
if (ret < 0) {
err("unable to get configuration (error=%d)", ret);
usb_destroy_configuration(dev);
clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
}
dev->actconfig = dev->config;
usb_set_maxpacket(dev);
return 1;
}
kfree(descriptor);
ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue);
if (ret < 0) {
err("failed to set active configuration (error=%d)", ret);
return ret;
}
for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
struct usb_interface *intf = &dev->actconfig->interface[i];
struct usb_interface_descriptor *as = &intf->altsetting[intf->act_altsetting];
ret = usb_set_interface(dev, as->bInterfaceNumber, as->bAlternateSetting);
if (ret < 0) {
err("failed to set active alternate setting for interface %d
(error=%d)", i, ret);
return ret;
}
}
return 0;
}
On 10/28/07, Oliver Neukum <[email protected]> wrote:
> Am Sonntag 28 Oktober 2007 schrieb Alan Stern:
> > You missed a critical piece of information: Jithu is using a 2.4
> > kernel.
>
> <censored> :-(
>
> Regards
> Oliver
>
>
// - my initial post
> Dear All,
>
> I am trying to implement a firmware upgrade for my usb smart card
> reader. (device firmware update procedure : I issue a switch to DFU
> control message and issue a usb_reset which makes the device
> re-enumerate as a DFU device with different VID/PID, after which I
> proceed with the f/w download)
>
> I am having a kernel level usb driver for my device (USB Smart card
> reader). When a user level application triggers a firm ware update :
> 1. i get the control in my kernel driver.
> 2. I send the switch to DFU control message to my device (which is
> ack ed by the device)
> 3. i issue a reset using usb_reset_device (defined in hub.c)
>
> The problem i am facing is that after issuing the "usb_reset_device
> (struct usb_device *dev) ", though i am able to see a reset in the
> CATC( USB protocol Analyzer) , the disconnect of the current usb
> client driver is not getting called and also the probe of the DFU
> driver is not getting called (the driver has support for both the
> VIDs/PIDs)
>
> Am i missing something - should i somehow notify the subystem to
> reenumerate the port or am i using the wrong call to reset
>
> At the CATC level i am seeing a reset, and the same address is
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel