Re: [Suggestion] drivers/usb/core: dev-config and dev->rawdescriptors, when processing failure.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



于 2012年12月06日 23:50, Alan Stern 写道:
> On Thu, 6 Dec 2012, Chen Gang wrote:
>> in drivers/usb/core/config.c, for function usb_get_configuration:
>>
>>   if processing failed at line 694, we will goto err2 (line 755..759) 
>>   in this condition, we do not free dev-config and dev->rawdescriptors.
> 
> This isn't necessary.  They are freed in usb_destroy_configuration().
> 
>>   after checking another relative source code, it seems not an issue (I am not quite sure).
>>   but I still suggest to:
>>     free them, when failure occurs
>>     or check them whether be NULL before new allocation, (if not NULL, free them firstly).
> 
> There never is any new allocation.  usb_get_configuration() is called 
> only once for any device.  (For an example of this sort of check, see 
> usb_enumerate_device() in hub.c.)
> 

  but I still not quite be sure, please help checking (total 3 steps, below).

  thanks.

------------------------------------------------------------------------------
Step 1:

in drivers/usb/core/sysfs.c:

  for the same device, can usb_dev_authorized_store be called multi-times ?
    according to the function comments, it seems can be called multi-times.

  and usb_dev_authorized_store may call usb_authorize_device at line 600..603


585 /*
586  * Authorize a device to be used in the system
587  *
588  * Writing a 0 deauthorizes the device, writing a 1 authorizes it.
589  */
590 static ssize_t usb_dev_authorized_store(struct device *dev,
591                                         struct device_attribute *attr,
592                                         const char *buf, size_t size)
593 {
594         ssize_t result;
595         struct usb_device *usb_dev = to_usb_device(dev);
596         unsigned val;
597         result = sscanf(buf, "%u\n", &val);
598         if (result != 1)
599                 result = -EINVAL;
600         else if (val == 0)
601                 result = usb_deauthorize_device(usb_dev);
602         else
603                 result = usb_authorize_device(usb_dev);
604         return result < 0? result : size;
605 }
606 
607 static DEVICE_ATTR_IGNORE_LOCKDEP(authorized, 0644,
608             usb_dev_authorized_show, usb_dev_authorized_store);
609 


------------------------------------------------------------------------------
Step 2:

in drivers/usb/core/hub.c:

   usb_authorize_device may call usb_enumerate_device at line 2355


2326 int usb_authorize_device(struct usb_device *usb_dev)
2327 {
2328         int result = 0, c;
2329 
2330         usb_lock_device(usb_dev);
2331         if (usb_dev->authorized == 1)
2332                 goto out_authorized;
2333 
2334         result = usb_autoresume_device(usb_dev);
2335         if (result < 0) {
2336                 dev_err(&usb_dev->dev,
2337                         "can't autoresume for authorization: %d\n", result);
2338                 goto error_autoresume;
2339         }
2340         result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor));
2341         if (result < 0) {
2342                 dev_err(&usb_dev->dev, "can't re-read device descriptor for "
2343                         "authorization: %d\n", result);
2344                 goto error_device_descriptor;
2345         }
2346 
2347         kfree(usb_dev->product);
2348         usb_dev->product = NULL;
2349         kfree(usb_dev->manufacturer);
2350         usb_dev->manufacturer = NULL;
2351         kfree(usb_dev->serial);
2352         usb_dev->serial = NULL;
2353 
2354         usb_dev->authorized = 1;
2355         result = usb_enumerate_device(usb_dev);
2356         if (result < 0)
2357                 goto error_enumerate;
2358         /* Choose and set the configuration.  This registers the interfaces
2359          * with the driver core and lets interface drivers bind to them.
2360          */
2361         c = usb_choose_configuration(usb_dev);
2362         if (c >= 0) {
2363                 result = usb_set_configuration(usb_dev, c);
2364                 if (result) {
2365                         dev_err(&usb_dev->dev,
2366                                 "can't set config #%d, error %d\n", c, result);
2367                         /* This need not be fatal.  The user can try to
2368                          * set other configurations. */
2369                 }
2370         }
2371         dev_info(&usb_dev->dev, "authorized to connect\n");
2372 
2373 error_enumerate:
2374 error_device_descriptor:
2375         usb_autosuspend_device(usb_dev);
2376 error_autoresume:
2377 out_authorized:
2378         usb_unlock_device(usb_dev);     // complements locktree
2379         return result;
2380 }



------------------------------------------------------------------------------
Step 3:

also in drivers/usb/core/hub.c:

  if udev->config != NULL:
    we will assume that it has already configured,
    and will not call usb_get_configuration again.

  if first call for usb_get_confiuration failed, may udev->config will not be NULL.
  and next call usb_enumerate_device, 
    we will misunderstand that it has already configured (all things are 0).
    is it match our original idea ?

2128 static int usb_enumerate_device(struct usb_device *udev)
2129 {
2130         int err;
2131 
2132         if (udev->config == NULL) {
2133                 err = usb_get_configuration(udev);
2134                 if (err < 0) {
2135                         dev_err(&udev->dev, "can't read configurations, error %d\n",
2136                                 err);
2137                         return err;
2138                 }
2139         }
2140         if (udev->wusb == 1 && udev->authorized == 0) {
2141                 udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
2142                 udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
2143                 udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
2144         }
2145         else {
2146                 /* read the standard strings and cache them if present */
2147                 udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
2148                 udev->manufacturer = usb_cache_string(udev,
2149                                                       udev->descriptor.iManufacturer);
2150                 udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
2151         }
2152         err = usb_enumerate_device_otg(udev);
2153         if (err < 0)
2154                 return err;
2155 
2156         usb_detect_interface_quirks(udev);
2157 
2158         return 0;
2159 }
2160 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux