I send you the usb_physical_reset_device for 2.6.0-test7 kernel. Now the reset works fine and as i 've told you after reset the device gets the same address.
Hope this will be added to the main kernel tree. ( along with exporting usb_physical_reset_device and prototyping inside usb.h).
Regards,
Stavros Markou.
int usb_physical_reset_device(struct usb_device *dev)
{
struct usb_device *parent = dev->parent;
struct usb_device_descriptor *descriptor;
int i, ret, port = -1, new_conf=0;
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;
descriptor = kmalloc(sizeof *descriptor, GFP_NOIO);
if (!descriptor) {
return -ENOMEM;
}
down(&usb_address0_sem);
/* Send a reset to the device */
if (hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
err("smarkou: attempting to reset root hub!");
hub_port_disable(parent, port);
up(&usb_address0_sem);
kfree(descriptor);
return(-ENODEV);
}
//[EMAIL PROTECTED]
dev->state = USB_STATE_DEFAULT;
/* Reprogram the Address */
ret = usb_set_address(dev);
if (ret < 0) {
err("USB device not accepting new address (error=%d)", ret);
hub_port_disable(parent, port);
up(&usb_address0_sem);
kfree(descriptor);
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.
*/
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);
//[EMAIL PROTECTED]
if (memcmp(&dev->descriptor, descriptor, sizeof(*descriptor))) {
new_conf = 1; //flag defined for us to know the descriptors
matching.
}
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 %s descriptor "
"(error=%d)", dev->devpath, ret);
else
err("USB device %s descriptor short read "
"(expected %Zi, got %i)",
dev->devpath,
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;
}
info("smarkou : After Getting the Configuration");
dev->actconfig = dev->config;
if(new_conf){
info("smarkou : FLAG Enabled");
return 1; //if the device descriptors don't match
}
info("smarkou : Before Set Configuration");
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_CONFIGURATION, 0,
dev->actconfig->desc.bConfigurationValue, 0,
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
if (ret < 0) {
err("failed to set dev %s active configuration (error=%d)",
dev->devpath, ret);
return ret;
}
dev->state = USB_STATE_CONFIGURED;
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf = dev->actconfig->interface[i];
struct usb_interface_descriptor *as;
as = &intf->altsetting[intf->act_altsetting].desc;
ret = usb_set_interface(dev, as->bInterfaceNumber,
as->bAlternateSetting);
info("smarkou : INSIDE FOR (%d)", i);
if (ret < 0) {
err("failed to set active alternate setting "
"for dev %s interface %d (error=%d)",
dev->devpath, i, ret);
return ret;
}
}
return 0;
}
