diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2007-08-14 09:15:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:51:01 -0400 |
commit | 7eff2e7a8b65c25920207324e56611150eb1cd9a (patch) | |
tree | 02a0eeba9d25d996233e30c18f258dfae0ae2139 /drivers/usb/core | |
parent | 8380770c842faef3001e44662953d64ad9a93663 (diff) |
Driver core: change add_uevent_var to use a struct
This changes the uevent buffer functions to use a struct instead of a
long list of parameters. It does no longer require the caller to do the
proper buffer termination and size accounting, which is currently wrong
in some places. It fixes a known bug where parts of the uevent
environment are overwritten because of wrong index calculations.
Many thanks to Mathieu Desnoyers for finding bugs and improving the
error handling.
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/driver.c | 29 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 28 |
2 files changed, 14 insertions, 43 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 63b1243a913..6273a5197e6 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -576,12 +576,9 @@ static int usb_device_match(struct device *dev, struct device_driver *drv) | |||
576 | } | 576 | } |
577 | 577 | ||
578 | #ifdef CONFIG_HOTPLUG | 578 | #ifdef CONFIG_HOTPLUG |
579 | static int usb_uevent(struct device *dev, char **envp, int num_envp, | 579 | static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) |
580 | char *buffer, int buffer_size) | ||
581 | { | 580 | { |
582 | struct usb_device *usb_dev; | 581 | struct usb_device *usb_dev; |
583 | int i = 0; | ||
584 | int length = 0; | ||
585 | 582 | ||
586 | if (!dev) | 583 | if (!dev) |
587 | return -ENODEV; | 584 | return -ENODEV; |
@@ -610,51 +607,39 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp, | |||
610 | * all the device descriptors we don't tell them about. Or | 607 | * all the device descriptors we don't tell them about. Or |
611 | * act as usermode drivers. | 608 | * act as usermode drivers. |
612 | */ | 609 | */ |
613 | if (add_uevent_var(envp, num_envp, &i, | 610 | if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d", |
614 | buffer, buffer_size, &length, | ||
615 | "DEVICE=/proc/bus/usb/%03d/%03d", | ||
616 | usb_dev->bus->busnum, usb_dev->devnum)) | 611 | usb_dev->bus->busnum, usb_dev->devnum)) |
617 | return -ENOMEM; | 612 | return -ENOMEM; |
618 | #endif | 613 | #endif |
619 | 614 | ||
620 | /* per-device configurations are common */ | 615 | /* per-device configurations are common */ |
621 | if (add_uevent_var(envp, num_envp, &i, | 616 | if (add_uevent_var(env, "PRODUCT=%x/%x/%x", |
622 | buffer, buffer_size, &length, | ||
623 | "PRODUCT=%x/%x/%x", | ||
624 | le16_to_cpu(usb_dev->descriptor.idVendor), | 617 | le16_to_cpu(usb_dev->descriptor.idVendor), |
625 | le16_to_cpu(usb_dev->descriptor.idProduct), | 618 | le16_to_cpu(usb_dev->descriptor.idProduct), |
626 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) | 619 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) |
627 | return -ENOMEM; | 620 | return -ENOMEM; |
628 | 621 | ||
629 | /* class-based driver binding models */ | 622 | /* class-based driver binding models */ |
630 | if (add_uevent_var(envp, num_envp, &i, | 623 | if (add_uevent_var(env, "TYPE=%d/%d/%d", |
631 | buffer, buffer_size, &length, | ||
632 | "TYPE=%d/%d/%d", | ||
633 | usb_dev->descriptor.bDeviceClass, | 624 | usb_dev->descriptor.bDeviceClass, |
634 | usb_dev->descriptor.bDeviceSubClass, | 625 | usb_dev->descriptor.bDeviceSubClass, |
635 | usb_dev->descriptor.bDeviceProtocol)) | 626 | usb_dev->descriptor.bDeviceProtocol)) |
636 | return -ENOMEM; | 627 | return -ENOMEM; |
637 | 628 | ||
638 | if (add_uevent_var(envp, num_envp, &i, | 629 | if (add_uevent_var(env, "BUSNUM=%03d", |
639 | buffer, buffer_size, &length, | ||
640 | "BUSNUM=%03d", | ||
641 | usb_dev->bus->busnum)) | 630 | usb_dev->bus->busnum)) |
642 | return -ENOMEM; | 631 | return -ENOMEM; |
643 | 632 | ||
644 | if (add_uevent_var(envp, num_envp, &i, | 633 | if (add_uevent_var(env, "DEVNUM=%03d", |
645 | buffer, buffer_size, &length, | ||
646 | "DEVNUM=%03d", | ||
647 | usb_dev->devnum)) | 634 | usb_dev->devnum)) |
648 | return -ENOMEM; | 635 | return -ENOMEM; |
649 | 636 | ||
650 | envp[i] = NULL; | ||
651 | return 0; | 637 | return 0; |
652 | } | 638 | } |
653 | 639 | ||
654 | #else | 640 | #else |
655 | 641 | ||
656 | static int usb_uevent(struct device *dev, char **envp, | 642 | static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) |
657 | int num_envp, char *buffer, int buffer_size) | ||
658 | { | 643 | { |
659 | return -ENODEV; | 644 | return -ENODEV; |
660 | } | 645 | } |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d8f7b089a8f..95a49d8efe7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1339,14 +1339,11 @@ void usb_release_interface(struct device *dev) | |||
1339 | } | 1339 | } |
1340 | 1340 | ||
1341 | #ifdef CONFIG_HOTPLUG | 1341 | #ifdef CONFIG_HOTPLUG |
1342 | static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | 1342 | static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) |
1343 | char *buffer, int buffer_size) | ||
1344 | { | 1343 | { |
1345 | struct usb_device *usb_dev; | 1344 | struct usb_device *usb_dev; |
1346 | struct usb_interface *intf; | 1345 | struct usb_interface *intf; |
1347 | struct usb_host_interface *alt; | 1346 | struct usb_host_interface *alt; |
1348 | int i = 0; | ||
1349 | int length = 0; | ||
1350 | 1347 | ||
1351 | if (!dev) | 1348 | if (!dev) |
1352 | return -ENODEV; | 1349 | return -ENODEV; |
@@ -1359,39 +1356,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | |||
1359 | alt = intf->cur_altsetting; | 1356 | alt = intf->cur_altsetting; |
1360 | 1357 | ||
1361 | #ifdef CONFIG_USB_DEVICEFS | 1358 | #ifdef CONFIG_USB_DEVICEFS |
1362 | if (add_uevent_var(envp, num_envp, &i, | 1359 | if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d", |
1363 | buffer, buffer_size, &length, | ||
1364 | "DEVICE=/proc/bus/usb/%03d/%03d", | ||
1365 | usb_dev->bus->busnum, usb_dev->devnum)) | 1360 | usb_dev->bus->busnum, usb_dev->devnum)) |
1366 | return -ENOMEM; | 1361 | return -ENOMEM; |
1367 | #endif | 1362 | #endif |
1368 | 1363 | ||
1369 | if (add_uevent_var(envp, num_envp, &i, | 1364 | if (add_uevent_var(env, "PRODUCT=%x/%x/%x", |
1370 | buffer, buffer_size, &length, | ||
1371 | "PRODUCT=%x/%x/%x", | ||
1372 | le16_to_cpu(usb_dev->descriptor.idVendor), | 1365 | le16_to_cpu(usb_dev->descriptor.idVendor), |
1373 | le16_to_cpu(usb_dev->descriptor.idProduct), | 1366 | le16_to_cpu(usb_dev->descriptor.idProduct), |
1374 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) | 1367 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) |
1375 | return -ENOMEM; | 1368 | return -ENOMEM; |
1376 | 1369 | ||
1377 | if (add_uevent_var(envp, num_envp, &i, | 1370 | if (add_uevent_var(env, "TYPE=%d/%d/%d", |
1378 | buffer, buffer_size, &length, | ||
1379 | "TYPE=%d/%d/%d", | ||
1380 | usb_dev->descriptor.bDeviceClass, | 1371 | usb_dev->descriptor.bDeviceClass, |
1381 | usb_dev->descriptor.bDeviceSubClass, | 1372 | usb_dev->descriptor.bDeviceSubClass, |
1382 | usb_dev->descriptor.bDeviceProtocol)) | 1373 | usb_dev->descriptor.bDeviceProtocol)) |
1383 | return -ENOMEM; | 1374 | return -ENOMEM; |
1384 | 1375 | ||
1385 | if (add_uevent_var(envp, num_envp, &i, | 1376 | if (add_uevent_var(env, "INTERFACE=%d/%d/%d", |
1386 | buffer, buffer_size, &length, | ||
1387 | "INTERFACE=%d/%d/%d", | ||
1388 | alt->desc.bInterfaceClass, | 1377 | alt->desc.bInterfaceClass, |
1389 | alt->desc.bInterfaceSubClass, | 1378 | alt->desc.bInterfaceSubClass, |
1390 | alt->desc.bInterfaceProtocol)) | 1379 | alt->desc.bInterfaceProtocol)) |
1391 | return -ENOMEM; | 1380 | return -ENOMEM; |
1392 | 1381 | ||
1393 | if (add_uevent_var(envp, num_envp, &i, | 1382 | if (add_uevent_var(env, |
1394 | buffer, buffer_size, &length, | ||
1395 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | 1383 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", |
1396 | le16_to_cpu(usb_dev->descriptor.idVendor), | 1384 | le16_to_cpu(usb_dev->descriptor.idVendor), |
1397 | le16_to_cpu(usb_dev->descriptor.idProduct), | 1385 | le16_to_cpu(usb_dev->descriptor.idProduct), |
@@ -1404,14 +1392,12 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | |||
1404 | alt->desc.bInterfaceProtocol)) | 1392 | alt->desc.bInterfaceProtocol)) |
1405 | return -ENOMEM; | 1393 | return -ENOMEM; |
1406 | 1394 | ||
1407 | envp[i] = NULL; | ||
1408 | return 0; | 1395 | return 0; |
1409 | } | 1396 | } |
1410 | 1397 | ||
1411 | #else | 1398 | #else |
1412 | 1399 | ||
1413 | static int usb_if_uevent(struct device *dev, char **envp, | 1400 | static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) |
1414 | int num_envp, char *buffer, int buffer_size) | ||
1415 | { | 1401 | { |
1416 | return -ENODEV; | 1402 | return -ENODEV; |
1417 | } | 1403 | } |