于 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