于 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html