Kitz Forum

Computer Software => Linux => Topic started by: Blackeagle on March 13, 2014, 11:10:51 AM

Title: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 13, 2014, 11:10:51 AM
Anyone know how to do this ?

I did some research and thought it should be possible with a udev rule, but upon trying it, I still see the kernel trying to interrogate the device which is what I want to avoid.

The udev rule I wrote is
Code: [Select]
BUS=="usb", ATTRS{idVendor}=="0547", ATTRS{idProduct}=="7000", OPTIONS+="ignore_device"
However, the output of dmesg still shows the kernel trying to talk to the device
Code: [Select]
dmesg | grep hid
[    2.374593] usbcore: registered new interface driver usbhid
[    2.374598] usbhid: USB HID core driver
[    2.378861] hid-generic 0003:04F2:0220.0001: input,hidraw0: USB HID v1.10 Keyboard [Chicony USB Wireless HID Receiver] on usb-0000:00:1d.3-2/input0
[    2.400109] hid-generic 0003:04F2:0220.0002: input,hiddev0,hidraw1: USB HID v1.10 Device [Chicony USB Wireless HID Receiver] on usb-0000:00:1d.3-2/input1
[    2.400996] hid-generic 0003:04F2:0220.0003: input,hidraw2: USB HID v1.10 Mouse [Chicony USB Wireless HID Receiver] on usb-0000:00:1d.3-2/input2
[   12.425647] hid-generic 0003:0547:7000.0004: timeout initializing reports
[   12.425953] hid-generic 0003:0547:7000.0004: hiddev0,hidraw3: USB HID v1.10 Device [HID 0547:7000] on usb-0000:00:1d.1-2.4/input0
[   22.429653] hid-generic 0003:0547:7000.0005: timeout initializing reports
[   22.430109] hid-generic 0003:0547:7000.0005: input,hidraw4: USB HID v1.10 Device [HID 0547:7000] on usb-0000:00:1d.1-2.4/input1
[   32.433435] hid-generic 0003:0547:7000.0006: timeout initializing reports
[   32.434072] hid-generic 0003:0547:7000.0006: input,hidraw5: USB HID v1.10 Device [HID 0547:7000] on usb-0000:00:1d.1-2.4/input2

The device in question is a Futaba USB LED display in a Spectra-FIC mediacentre case. I have (after much searching) found some code that can apparently drive the display to a certain extent under linux, but, the guy that wrote said code stated that the display crashes when the kernel tries to obtain a report from it.  This is borne out by the timeouts above.

His solution was to add a quirk to the kernel by calling  "usbhid_modify_dquirk()" from his kernel module but there does not seem to be this symbol in my kernel  :no: or at least I cannot find it in System.map

I'd really like to get this display to at least be able to do something under Linux as this machine is in daily use !!

Linux version is Ubuntu 12.10 - (GNU/Linux 3.5.0-41-generic i686)

uname -a Linux xbmc-desktop 3.5.0-41-generic #64-Ubuntu SMP Wed Sep 11 15:40:48 UTC 2013 i686 i686 i686 GNU/Linux

Link to source of information (http://www.parsonscroft.plus.com/steve/mythtv/)

My thinking was that if I could stop the kernel from interrogating the device, I could skip adding the quirk and move to the driver.

Help would be much appreciated (https://forum.kitz.co.uk/proxy.php?request=http%3A%2F%2Fwww.emotionless.co.uk%2Femotes%2Fa%2Fhelpme.gif&hash=f5e49fbebf9ad27caf62a4db1542f952)
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: roseway on March 13, 2014, 11:22:08 AM
I confess I know next to nothing about udev rules. It's easy enough to blacklist a kernel module (see https://wiki.debian.org/KernelModuleBlacklisting ) but I guess that isn't what you want.
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 13, 2014, 11:58:47 AM
No, sadly it's not Eric.

However, perusal of the latest stable kernel source reveals a "hid-ids.h" file which is referenced in "hid-quirks.c".  This second file does contain "usbhid_modify_dquirk()" which is for modifying quirks dynamically, but as it's neither exported nor listed in System.map, I cannot call it.

So, what I have done (and this is all extremely experimental !!) is modify the hids-ids.h file to include the required device
Code: [Select]
~snip
#define USB_VENDOR_ID_FLATFROG 0x25b5
#define USB_DEVICE_ID_MULTITOUCH_3200 0x0002

#define USB_VENDOR_ID_FUTABA 0x0547
#define USB_DEVICE_ID_LED_DISPLAY 0x7000

#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
snip~

And then further modify "hid-quirks.c" to load the quirk against the device (I think  ???)

Code: [Select]
~snip
        { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
snip~

Next step is to SCP the modified kernel code to the target machine (as it's all administered remotely) and see if it will compile !!  ???
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: burakkucat on March 13, 2014, 04:11:40 PM
I make us of this link (http://www.reactivated.net/writing_udev_rules.html) when attempting to write UDEV rules. As it is something I do not often do, getting the rule "just right" usually takes multiple iterations . . .
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 13, 2014, 06:39:39 PM
Thanks b*cat.  That's actually the page I visited to try and work it out.  Kernel is built now though and installed and I'm just in the process of installing the nVidia drivers.  I've now found out though that I could have simply added 'EXPORT_SYMBOL(usbhid_modify_dquirk)' to hid-quirks.c to expose the relevant symbol in System.map. Doh !!


*edit*

Seems like my mod has worked !!

Code: [Select]
dmesg | grep hid
[    6.716255] hidraw: raw HID events driver (C) Jiri Kosina
[    6.851944] usbcore: registered new interface driver usbhid
[    6.851951] usbhid: USB HID core driver
[    6.861334] hid-generic 0003:04F2:0220.0001: input,hidraw0: USB HID v1.10 Keyboard [Chicony USB Wireless HID Receiver] on usb-0000:00:1d.3-2/input0
[    7.244774] hid-generic 0003:04F2:0220.0002: input,hiddev0,hidraw1: USB HID v1.10 Device [Chicony USB Wireless HID Receiver] on usb-0000:00:1d.3-2/input1
[    7.246083] hid-generic 0003:04F2:0220.0003: input,hidraw2: USB HID v1.10 Mouse [Chicony USB Wireless HID Receiver] on usb-0000:00:1d.3-2/input2
[    7.261948] hid-generic 0003:0547:7000.0004: hiddev0,hidraw3: USB HID v1.10 Device [HID 0547:7000] on usb-0000:00:1d.1-2.4/input0
[    7.264816] hid-generic 0003:0547:7000.0005: input,hidraw4: USB HID v1.10 Device [HID 0547:7000] on usb-0000:00:1d.1-2.4/input1
[    7.267770] hid-generic 0003:0547:7000.0006: input,hidraw5: USB HID v1.10 Device [HID 0547:7000] on usb-0000:00:1d.1-2.4/input2

No more timeouts waiting for reports !!  I'm like a furry purry thing with several tails  :lol:

Sooo, next thing to do is build the driver for the display and 'insmod' it.
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: burakkucat on March 13, 2014, 06:52:37 PM
I've now found out though that I could have simply added 'EXPORT_SYMBOL(usbhid_modify_dquirk)' to hid-quirks.c to expose the relevant symbol in System.map. Doh !!

D'oh! indeed.  ;D
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 13, 2014, 08:50:26 PM
Oh, ha ha !!  ::)  I will know next time (this time ??)

Actually, having got this far I was quite pleased.  Pitfall 1 however was the fact the nVidia driver would not install.  A quick search showed that I needed a later version, so having duly downloaded and compiled it, I managed to get X running again.

Pitfall 2 was that I forgot to enable lirc support in the kernel when I built it, so when I fired up XBMC on the machine, the remote didn't work.  I have now configured the kernel correctly (I think  ???) so it should create /dev/lirc0 which is currently missing.

Re-building the kernel though will have to wait until tomorrow, as the machine will be needed shortly (I can still use a tablet to control XBMC via http) and compile time was roughly two hours or so.

I am learning a lot as I go, even though it's a steep curve.   That display better show something for all of this  :o
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 14, 2014, 02:05:44 PM
lol, replying to myself, but then I can look back later at what I did, when I forget (which I will!!).

Kernel rebuilt with lirc support and a lot of extraneous stuff removed such as laptop and hardware drivers I won't ever need. Having compiled the kernel with the necessary quirk added for the display, the 'futabaquirks.ko' module written by Steve Williams (http://www.parsonscroft.plus.com/steve/mythtv/page2.html) is no longer needed and the userspace driver does indeed show the current time on the display  ;D ;D

Glorious as this is (because I thought initially I would never get it to work under Linux), it is only the first step  :o  This is though, where I may come majorly unstuck, as I know very little 'C'.  What I want to do is adapt the driver to work with LCDproc as XBMC includes its own version and would therefore be able to drive the display.  Failing that, the aforementioned SW has written a kernel space driver, which
Quote
This driver when it has grabbed the LCD will print its device
 * major number in the system log. You need to create a char device at that node
 * and then any string written to that device will appear on the display

I could in that case possibly write some python to communicate with XBMC's JSON interface and write to the char device.  The former would be my preferred choice and I have downloaded the source for LCDproc to see what needs doing.  I can see myself taking a very intensive 'crash course' in C over the next few days.

Obviously as the machine is now back up, running and all controlled by remote as before, Sarah is back to being pleased and as I'm only going to be messing with the display driver, hopefully nothing to drastic will occur (famous last words?).

I've seen a few people with this case ask about a Linux driver for it on the XBMC forum, so if I can manage to get something working, then hopefully it'll benefit more than just me.

Fortunately, Steve was good enough to GPL his code and if I do manage to get something working, I will of course give him full credit as the original author.

Oh, if anyone feels that they can help out in any way, or just wants a good laugh at my lack of coding expertise, then please, feel free !!

Cheers, BE.
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: roseway on March 14, 2014, 03:18:28 PM
I would like to help, but my knowledge of C is almost certainly less than yours. :)
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 14, 2014, 07:36:49 PM
B'eagle is tempted to disbelieve roseway  :o
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: roseway on March 14, 2014, 09:06:03 PM
Honestly, what little C programming I ever did was about 15 years ago, and I barely remember a thing.
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 16, 2014, 06:10:15 PM
lol, that's ok, I think I've barely learnt a thing !!!  Spent two days wrestling with pointers and casting stuff but with the help of dissecting several of the existing LCDproc drivers and the code I originally obtained, I've now got to the point where not only does my module compile, but LCDproc recognises it as an output driver and the whole shebang compiles correctly.

Unfortunately, and this is bouncing my brain currently, LCDproc loads my driver, and then unloads it again with a message 'undefined symbol: libusb_release_interface'.  Obviously, as it compiles correctly then this isn't the case.  I'm just wondering now as I write this, whether I should have included @LIBUSB_1_0_CFLAGS@ as well as @LIBUSB_CFLAGS@ and the other libusb_1_0 stuff too.

Hmmmmm, b'eagle goes off to investigate !
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 17, 2014, 10:52:43 AM
 :clap: Major breakthrough this morning !!!  Not only have I found and fixed the error causing the seg fault, but the driver is now communicating with LCDd and I get text on my display !!!  Unfortunately, it's currently flickering like mad so that's the next thing to address. I presume at this stage that it's because LCDd prepares several 'screens' of info, and then rotates them onto the display in turn.  It's likely not helped because the display graphically is so small - just 7 letters - although the driver is meant to scroll longer strings across it.
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: roseway on March 17, 2014, 12:59:45 PM
Great stuff! :clap2:
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: tickmike on March 18, 2014, 11:18:59 AM
Hi, just seen this  :(
On PCLinuxOS we open   /etc/modprobe.d  as root or 'super user' and add your device to the 'blacklist' with a text Editor, then reboot.
Simple. ;)
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 18, 2014, 01:45:34 PM
Hi mike  :thumbs:

I was going to look into it further (the blacklisting), but I ended up modding the kernel directly to not try and obtain a report from the display, and then building it from scratch.

This worked and now it appears, at least at the moment, that my driver works with LCDd. At the moment it's running on the target machine with XBMC and scrolling the time and date across the display.  Navigating to area's of XBMC are reflected on the display, as is the name of the TV station etc.

Much further testing is required to ensure that the driver is stable, with no memory leaks etc but so far so good !!  I might add that had I still been running an OS from Billy G, I wouldn't have even attempted to write a device driver, let alone actually managed it !!

B*eagle is feeling rather proud right now  :-[ :blush:
Title: Re: How do I blacklist a specific USB device at boot ?
Post by: Blackeagle on March 23, 2014, 07:21:01 PM
Further development is ongoing !!

I had hoped that as the LCDd server implements icons, that it would be possible to drive the custom icons on the display using it's standard icon output, but sadly this doesn't seem to be the case.  :no:

All I ever get returned from the XBMC client is a 'filled block' icon which is obviously no use. I have, as a 'proof of concept' enabled some checking of the strings scrolling across the display to light such icons as 'music', 'tv', 'photos' etc but as this is not in the spirit of LCDproc, I would hesitate to continue down this route and I did it purely to ensure I was driving the display correctly.

Having looked at drivers for LCD's that have custom icons (imon/mdm166a) reveals that one can send raw data to LCDd, provided the client supports doing this.  This is how the custom icons are driven for those displays.  If the client doesn't implement the raw output, then those icons will not work, but the basic display will.

So, as my driver implements the basics, we now have to turn to the client (in this case an add-on for XBMC) to see what information is returned.  Looking at the code for the iMon driver, it appears that volume level and pretty much any icon I could want are supported for that display.

Unfortunately for me, it's all python, which means trying to get my head around another language  :'(  At this moment I think I would rather have it written in C !!!

Plans as of now are to fork the current development branch of the XBMC LCDproc add-on and try an implement icon support for my display.  As all their code is GPL'd there's no problem doing that, or indeed hosting my own version of their addon.

It is an old case, and I doubt that there are all that many out there anymore, otherwise if I can get it working, I'd submit both the XBMC code and the LCDproc driver to the relevant places for inclusion in their software.  I am however, very pleased to see my display working after several years of being blank and although it's limited in what it can do, I have no intentions of changing cases anytime soon.