Hi Oliver,

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;
}

Reply via email to