Re: [PATCH] Explicitly disable BT radio using rfkill interface on suspend

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

 



Hi Kay:

Kay Sievers wrote:
>
> What the action you want to take at removal? You can set
> ENV{REMOVE_CMD}= and it will be passed to RUN+= for that exact device
> when it goes away.
>
> You can also just store any other custom property in the udev
> database, and it will be there on remove.
>   
Thanks for the recommendation on ENV{REMOVE_CMD}.  With some minor
modifications to my old patch, I've got it working using ENV{REMOVE_CMD}
now reliably post suspend.

Although rewalking the child devices to find the right one to prod might
seem tedious, it should be more future-proof in case later hardware ends
up changing.

Would you mind reviewing the attached patch for submission to udev then?

Thanks,
-- 
Mario Limonciello
*Dell | Linux Engineering*
mario_limonciello@xxxxxxxx
=== modified file 'extras/hid2hci/70-hid2hci.rules'
--- extras/hid2hci/70-hid2hci.rules	2009-06-26 06:17:23 +0000
+++ extras/hid2hci/70-hid2hci.rules	2009-07-14 17:25:17 +0000
@@ -11,6 +11,17 @@
 ATTR{bInterfaceClass}=="03", ATTR{bInterfaceSubClass}=="01", ATTR{bInterfaceProtocol}=="02", ATTRS{bDeviceClass}=="00", ATTRS{idVendor}=="413c", ATTRS{bmAttributes}=="e0", \
     RUN+="hid2hci --method dell -v $attr{idVendor} -p $attr{idProduct} --mode hci"
 
+# When a Dell device recovers from S3, the mouse child needs to be repoked
+# Well, unfortunately the only event we see is the BT device disappearing, so
+# we have to run with that and chase down the mouse device on USB bus as a child.
+ATTR{bDeviceClass}=="e0", \
+ATTR{bDeviceSubClass}=="01", \
+ATTR{bDeviceProtocol}=="01", \
+ATTR{idVendor}=="413c", \
+ATTR{bmAttributes}=="e0", \
+IMPORT{parent}="ID_*", \
+ENV{REMOVE_CMD}="hid2hci --method dell -v $env{ID_VENDOR_ID} -p $env{ID_MODEL_ID} --mode hci -s 02"
+
 ENV{DEVTYPE}!="usb_device", GOTO="hid2hci_end"
 
 # Logitech devices

=== modified file 'extras/hid2hci/hid2hci.c'
--- extras/hid2hci/hid2hci.c	2009-06-16 17:30:22 +0000
+++ extras/hid2hci/hid2hci.c	2009-07-14 17:20:01 +0000
@@ -271,6 +271,28 @@
 	return 0;
 }
 
+static struct usb_device* find_resuscitated_device(uint16_t base_vendor, uint16_t base_product, uint8_t bInterfaceProtocol)
+{
+	struct usb_bus *bus;
+	struct usb_device *dev;
+	int i,j,k,l;
+
+	usb_find_busses();
+	usb_find_devices();
+
+	for (bus = usb_get_busses(); bus; bus = bus->next)
+		for (dev = bus->devices; dev; dev = dev->next)
+			if (dev->descriptor.idVendor == base_vendor &&
+			    dev->descriptor.idProduct == base_product)
+				for (i = 0; i < dev->num_children; i++)
+					for (j = 0; j < dev->children[i]->descriptor.bNumConfigurations; j++)
+						for (k = 0; k < dev->children[i]->config[j].bNumInterfaces; k++)
+							for (l = 0; l < dev->children[i]->config[j].interface[k].num_altsetting; l++)
+								if (dev->children[i]->config[j].interface[k].altsetting[l].bInterfaceProtocol == bInterfaceProtocol)
+									return dev->children[i];
+	return NULL;
+}
+
 static void usage(char* error)
 {
 	if (error)
@@ -289,6 +311,7 @@
 		"\t-v, --vendor=        Vendor ID to act upon\n"
 		"\t-p, --product=       Product ID to act upon\n"
 		"\t-m, --method=        Method to use to switch [csr, logitech, dell]\n"
+		"\t-s, --resuscitate=   Find the child device with this bInterfaceProtocol to run on \n"
 		"\n");
 	if (error)
 		exit(1);
@@ -301,6 +324,7 @@
 	{ "vendor",	required_argument, 0, 'v' },
 	{ "product",	required_argument, 0, 'p' },
 	{ "method",	required_argument, 0, 'm' },
+	{ "resuscitate",required_argument, 0, 's' },
 	{ 0, 0, 0, 0 }
 };
 
@@ -309,8 +333,9 @@
 	struct device_info dev = { NULL, HCI, 0, 0 };
 	int opt, quiet = 0;
 	int (*method)(struct device_info *dev) = NULL;
+	uint8_t resuscitate = 0;
 
-	while ((opt = getopt_long(argc, argv, "+r:v:p:m:qh", main_options, NULL)) != -1) {
+	while ((opt = getopt_long(argc, argv, "+s:r:v:p:m:qh", main_options, NULL)) != -1) {
 		switch (opt) {
 		case 'r':
 			if (optarg && !strcmp(optarg, "hid"))
@@ -339,6 +364,9 @@
 		case 'q':
 			quiet = 1;
 			break;
+		case 's':
+			sscanf(optarg, "%2hx", (short unsigned int*) &resuscitate);
+			break;
 		case 'h':
 			usage(NULL);
 		default:
@@ -355,7 +383,16 @@
 
 	usb_init();
 
-	if (!find_device(&dev)) {
+	if (resuscitate) {
+		dev.dev = find_resuscitated_device(dev.vendor, dev.product, resuscitate);
+		if (!quiet && !dev.dev) {
+			fprintf(stderr, "Device %04x:%04x was unable to resucitate any child devices.\n",dev.vendor,dev.product);
+			exit(1);
+		}
+		dev.vendor = dev.dev->descriptor.idVendor;
+		dev.product = dev.dev->descriptor.idProduct;
+	}
+	else if (!find_device(&dev)) {
 		if (!quiet)
 			fprintf(stderr, "Device %04x:%04x not found on USB bus.\n",
 				dev.vendor, dev.product);

Attachment: signature.asc
Description: OpenPGP digital signature


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

  Powered by Linux