linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mario Limonciello <mario_limonciello@dell.com>
To: linux-hotplug@vger.kernel.org
Subject: Re: [PATCH] Explicitly disable BT radio using rfkill interface on
Date: Tue, 30 Jun 2009 22:02:21 +0000	[thread overview]
Message-ID: <4A4A8B6D.3060509@dell.com> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 2006 bytes --]

Hi Alan:


Alan Stern wrote:
> On Wed, 20 May 2009, Mario Limonciello wrote:
>
>   
>
> 	echo 0 >/sys/bus/usb/devices/.../power/persist
>
> This will also prevent reset-resume after hibernation.
>
>   
Yes, as it turns out this works properly for a single resume if I apply
that to the bits of all the child devices.  I take it that bit is just
for debugging purposes, and any solution centered around it would not be
a good solution.
>
> You can't.  Instead you have to arrange things so that when the
> intentional change was made, it left behind a timestamp indicator.  If
> that timestamp if present and not more than a few seconds in the past,
> you know the change was intentional.
>
>
>   
So I took up your advice here and tried to assemble a new udev rule and
function that would get called out upon when coming out of S3. It takes
the Vendor and Product IDs of the parent device of the device we just
lost and passes them to the new function.  The new function then tries
to walk that USB bus again to find the child device that it is supposed
to operate upon.

There is "remove" event in the udev log for that BT radio child device. 
I tried to extract as many attributes as I could from that information
and put it in the rule.  The details from this are in attribute_walk.out
(attached).

Unfortunately, this rule isn't getting ran after S3 even though I see
the remove event.  I can run udevadm test PATH (where PATH is the one of
the BT device we lost) and see that it should be spawning the rule.

However, running udevadm test -a remove PATH, I just see that the rule
gets matched, but not executed.  I can't help but think this is all very
close to functional and there is either something silly i'm doing wrong
or a deficiency of udev that's preventing the attributes from being
matched on the removal event.  Would you mind taking a look and/or
commenting?

-- 
Mario Limonciello
*Dell | Linux Engineering*
mario_limonciello@dell.com

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: resuscitate.patch --]
[-- Type: text/x-patch; name="resuscitate.patch", Size: 4327 bytes --]

=== 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-06-30 21:49:54 +0000
@@ -1,7 +1,7 @@
 # do not edit this file, it will be overwritten on update
 
-ACTION!="add", GOTO="hid2hci_end"
 SUBSYSTEM!="usb", GOTO="hid2hci_end"
+ACTION!="add|change", GOTO="addchange_end"
 
 # Variety of Dell Bluetooth devices - it looks like a bit of an odd rule,
 # because it is matching on a mouse device that is self powered, but that
@@ -22,4 +22,17 @@
 ATTR{idVendor}=="0458", ATTR{idProduct}=="1000", RUN+="hid2hci --method csr -v $attr{idVendor} -p $attr{idProduct} --mode hci"
 ATTR{idVendor}=="05ac", ATTR{idProduct}=="1000", RUN+="hid2hci --method csr -v $attr{idVendor} -p $attr{idProduct} --mode hci"
 
+LABEL="addchange_end"
+
+# 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_*", \
+RUN+="hid2hci --method dell -v $env{ID_VENDOR_ID} -p $env{ID_MODEL_ID} --mode hci -s 02"
+
 LABEL="hid2hci_end"

=== modified file 'extras/hid2hci/hid2hci.c'
--- extras/hid2hci/hid2hci.c	2009-06-16 17:30:22 +0000
+++ extras/hid2hci/hid2hci.c	2009-06-30 21:49:27 +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"))
@@ -341,6 +366,9 @@
 			break;
 		case 'h':
 			usage(NULL);
+        case 's':
+            sscanf(optarg, "%2hx", (short unsigned int*) &resuscitate);
+            break;
 		default:
 			exit(0);
 		}
@@ -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 #1.3: attribute_walk.out --]
[-- Type: text/plain, Size: 3589 bytes --]


Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:04.0/usb3/3-4/3-4.3':
    KERNEL=="3-4.3"
    SUBSYSTEM=="usb"
    DRIVER=="usb"
    ATTR{configuration}==""
    ATTR{bNumInterfaces}==" 4"
    ATTR{bConfigurationValue}=="1"
    ATTR{bmAttributes}=="e0"
    ATTR{bMaxPower}=="100mA"
    ATTR{urbnum}=="186"
    ATTR{idVendor}=="413c"
    ATTR{idProduct}=="8156"
    ATTR{bcdDevice}=="0172"
    ATTR{bDeviceClass}=="e0"
    ATTR{bDeviceSubClass}=="01"
    ATTR{bDeviceProtocol}=="01"
    ATTR{bNumConfigurations}=="1"
    ATTR{bMaxPacketSize0}=="64"
    ATTR{speed}=="12"
    ATTR{busnum}=="3"
    ATTR{devnum}=="7"
    ATTR{version}==" 2.00"
    ATTR{maxchild}=="0"
    ATTR{quirks}=="0x0"
    ATTR{authorized}=="1"
    ATTR{manufacturer}=="Dell Computer Corp"
    ATTR{product}=="Dell Wireless 370 Bluetooth Mini-card"

  looking at parent device '/devices/pci0000:00/0000:00:04.0/usb3/3-4':
    KERNELS=="3-4"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}==" 94mA"
    ATTRS{urbnum}=="195"
    ATTRS{idVendor}=="0a5c"
    ATTRS{idProduct}=="4500"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{speed}=="12"
    ATTRS{busnum}=="3"
    ATTRS{devnum}=="2"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="3"
    ATTRS{quirks}=="0x0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Broadcom"
    ATTRS{product}=="BCM2046B1"

  looking at parent device '/devices/pci0000:00/0000:00:04.0/usb3':
    KERNELS=="usb3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{urbnum}=="75"
    ATTRS{idVendor}=="1d6b"
    ATTRS{idProduct}=="0001"
    ATTRS{bcdDevice}=="0206"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="12"
    ATTRS{busnum}=="3"
    ATTRS{devnum}=="1"
    ATTRS{version}==" 1.10"
    ATTRS{maxchild}=="4"
    ATTRS{quirks}=="0x0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 2.6.30-10-generic ohci_hcd"
    ATTRS{product}=="OHCI Host Controller"
    ATTRS{serial}=="0000:00:04.0"
    ATTRS{authorized_default}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:04.0':
    KERNELS=="0000:00:04.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="ohci_hcd"
    ATTRS{vendor}=="0x10de"
    ATTRS{device}=="0x0aa5"
    ATTRS{subsystem_vendor}=="0x1028"
    ATTRS{subsystem_device}=="0x0271"
    ATTRS{class}=="0x0c0310"
    ATTRS{irq}=="21"
    ATTRS{local_cpus}=="ff"
    ATTRS{local_cpulist}=="0-7"
    ATTRS{modalias}=="pci:v000010DEd00000AA5sv00001028sd00000271bc0Csc03i10"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}==""

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

             reply	other threads:[~2009-06-30 22:02 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-30 22:02 Mario Limonciello [this message]
2009-06-30 22:26 ` [PATCH] Explicitly disable BT radio using rfkill interface on Kay Sievers
2009-07-01  3:53 ` [PATCH] Explicitly disable BT radio using rfkill interface on suspend Mario_Limonciello
2009-07-01 12:06 ` [PATCH] Explicitly disable BT radio using rfkill interface on Marcel Holtmann
2009-07-01 13:13 ` [PATCH] Explicitly disable BT radio using rfkill interface on suspend Mario_Limonciello
2009-07-01 15:03 ` [PATCH] Explicitly disable BT radio using rfkill interface on Marcel Holtmann
2009-07-01 17:12 ` Mario Limonciello
2009-07-01 17:18 ` Matthew Garrett
2009-07-01 22:13 ` Marcel Holtmann
2009-07-01 22:16 ` Matthew Garrett
2009-07-01 22:23 ` Mario Limonciello
2009-07-01 22:49 ` Marcel Holtmann
2009-07-01 22:52 ` Matthew Garrett
2009-07-02 14:02 ` Alan Stern
2009-07-10 14:46 ` Alan Stern
2009-07-14 16:40 ` Mario Limonciello
2009-07-14 16:51 ` Alan Stern
2009-07-14 16:52 ` Kay Sievers
2009-07-14 17:32 ` Mario Limonciello
2009-07-14 18:46 ` Marcel Holtmann
2009-07-14 19:12 ` Kay Sievers
2009-07-14 21:00 ` Mario Limonciello
2009-07-14 21:20 ` Marcel Holtmann
2009-07-14 21:24 ` Kay Sievers
2009-07-14 22:45 ` Kay Sievers
2009-07-15  2:07 ` Alan Stern
2009-07-15  2:26 ` Kay Sievers
2009-07-15 22:15 ` Mario Limonciello
2009-07-15 22:24 ` Mario Limonciello
2009-07-15 23:27 ` Kay Sievers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4A4A8B6D.3060509@dell.com \
    --to=mario_limonciello@dell.com \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).