You are not logged in.
Hi,
I have problems with systemd. I want to upload a firmware to my bluetooth adapter which needs the device already created by bluetoothd. I made the service file /usr/lib/systemd/system/fw-upload-bcm20702a0.service
Unit]
Description=uploading firmware to BCM20702A0 buetooth adapter
Requires=bluetooth.service
After=bluetooth.service
[Service]
Type=oneshot
ExecStart=/usr/bin/brcm_patchram_plus_usb --patchram /lib/firmware/BCM20702A0_001.001.024.0156.0204.hcd hci0
[Install]
Alias=fw-upload-bcm20702a0.service
WantedBy=graphical.target
Manually executing this after system startup with
systemctl start fw-upload-bcm20702a0.service
works. But during system startup I get this error:
[root@gruenix ~]# systemctl status fw-upload-bcm20702a0.service
fw-upload-bcm20702a0.service - uploading firmware to BCM20702A0 buetooth adapter
Loaded: loaded (/usr/lib/systemd/system/fw-upload-bcm20702a0.service; enabled)
Active: failed (Result: exit-code) since Mo 2013-04-15 10:39:15 CEST; 36s ago
Process: 1273 ExecStart=/usr/bin/brcm_patchram_plus_usb --patchram /lib/firmware/BCM20702A0_001.001.024.0156.0204.hcd hci0 (code=exited, status=1/FAILURE)
Apr 15 10:39:15 gruenix brcm_patchram_plus_usb[1273]: device hci0 could not be found
Apr 15 10:39:15 gruenix brcm_patchram_plus_usb[1273]: option patchram with arg /lib/firmware/BCM20702A0_001.001.024.0156.0204.hcd
Apr 15 10:39:15 gruenix systemd[1]: fw-upload-bcm20702a0.service: main process exited, code=exited, status=1/FAILURE
Apr 15 10:39:15 gruenix brcm_patchram_plus_usb[1273]: hci0
Apr 15 10:39:15 gruenix systemd[1]: Failed to start uploading firmware to BCM20702A0 buetooth adapter.
Apr 15 10:39:15 gruenix systemd[1]: Unit fw-upload-bcm20702a0.service entered failed state
The error indicates that the device hci0 is not created in time. But what else can I do to assure that?
Harvey
Last edited by Harey (2013-08-14 09:49:22)
Linux is like a wigwam: No Gates, no Windows and an Apache inside
Offline
Does hci0 show up as a .device unit in systemctl? If so, you could use Requires=sys-path-to-bluetooth.device or BindsTo=sys-path-to-bluetooth.device to ensure that the device is present before the service starts.
Offline
I have sys-subsystem-bluetooth-devices-hci0.device in systemctl output but if I change Requires= to
Requires=sys-subsystem-bluetooth-devices-hci0.device
the error is the same: device hci0 could not be found...
This drives me nuts
Harvey
BTW, couldn't find BindsTo here:
http://www.freedesktop.org/software/sys … rvice.html
Last edited by Harey (2013-04-15 11:33:35)
Linux is like a wigwam: No Gates, no Windows and an Apache inside
Offline
Requires/BindsTo does not imply After, you will also have to add:
After=sys-subsystem-bluetooth-devices-hci0.device
this is explained in "man systemd.unit" btw.
Offline
Thanks for your help which is greatly appreceated.
But... no luck.
[root@gruenix ~]# systemctl | grep hci0
sys-devices-pci0000:00-0000:00:1d.0-usb4-4\x2d1-4\x2d1.4-4\x2d1.4:1.0-bluetooth-hci0.device loaded active plugged /sys/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.4/4-1.4:1.0/bluetooth/hci0
sys-subsystem-bluetooth-devices-hci0.device loaded active plugged /sys/subsystem/bluetooth/devices/hci0
My service file /usr/lib/systemd/system/fw-upload-bcm20702a0.service:
[Unit]
Description=uploading firmware to BCM20702A0 buetooth adapter
Requires=sys-subsystem-bluetooth-devices-hci0.device
BindsTo=sys-subsystem-bluetooth-devices-hci0.device
After=sys-subsystem-bluetooth-devices-hci0.device
[Service]
Type=oneshot
ExecStart=/usr/bin/brcm_patchram_plus_usb --patchram /lib/firmware/BCM20702A0_001.001.024.0156.0204.hcd hci0
[Install]
Alias=fw-upload-bcm20702a0.service
WantedBy=graphical.target
Still no luck:
[root@gruenix ~]# systemctl status fw-upload-bcm20702a0.service
fw-upload-bcm20702a0.service - uploading firmware to BCM20702A0 buetooth adapter
Loaded: loaded (/usr/lib/systemd/system/fw-upload-bcm20702a0.service; enabled)
Active: failed (Result: exit-code) since Mo 2013-04-15 14:43:14 CEST; 35min ago
Process: 1227 ExecStart=/usr/bin/brcm_patchram_plus_usb --patchram /lib/firmware/BCM20702A0_001.001.024.0156.0204.hcd hci0 (code=exited, status=1/FAILURE)
Apr 15 14:43:14 gruenix brcm_patchram_plus_usb[1227]: device hci0 could not be found
Apr 15 14:43:14 gruenix brcm_patchram_plus_usb[1227]: option patchram with arg /lib/firmware/BCM20702A0_001.001.024.0156.0204.hcd
Apr 15 14:43:14 gruenix brcm_patchram_plus_usb[1227]: hci0
What's wrong?
Harvey
Linux is like a wigwam: No Gates, no Windows and an Apache inside
Offline
And to complicate this further, the firmware upload has to be redone each time the system was in suspend to ram/disk...
Harvey
Linux is like a wigwam: No Gates, no Windows and an Apache inside
Offline
Today I revisited my problem and solved it. Just in case anybody is interested in the solution:
Preface: You need 2 small packages for this to work
1. hex2hcd - converts a hex file extracted from the windows driver package to hcd format
2. brcm_patchram_plus - a tool from broadcom to upload firmware files into the usb adpater
I made to AUR packages for convenience:
https://aur.archlinux.org/packages/?O=0&K=hex2hcd-git
and
https://aur.archlinux.org/packages/brcm … _plus-git/
Then you convert your windows firmware file to hcd format with hex2hcd and store it as /lib/firmware/fw-{vendor_id}_{device_id}.hcd (in my case: /lib/firmware/fw-0489_e031.hcd).
Now for the tricky part part: Create a script like this (improvements and comments welcome):
#!/bin/bash
#
# BCM20702A0 BT Adapter upload rampatch
# env Variables
logfile=/var/log/rampatch.log
# logfile check
if ! test -f ${logfile} ; then
# logfile does not exist, so create it
touch $logfile
fi
echo "-------------------------------------------------------" >> $logfile
entrytime=$(date +"%Y-%m-%d %H:%M:%S")
echo $entrytime " applying rampatch to BCM20702A0 bluetooth adapter" >> $logfile
# wait for hci0 to become available and usable
sleep 1
/usr/bin/brcm_patchram_plus_usb --patchram /lib/firmware/fw-0489_e031.hcd hci0 >> $logfile
entrytime=$(date +"%Y-%m-%d %H:%M:%S")
echo $entrytime " ..done" >> $logfile
echo "-------------------------------------------------------" >> $logfile
(This one writes to a logfile in /var/log/ for easier debugging)
This has to be triggered by systemd, so we need a service file /etc/systemd/system/loadfw.service:
[Unit]
Description=Load firmware into BCM20702A0 bluetooth USB adapter
After=basic.target
After=suspend.target
After=hibernate.target
[Service]
Type=oneshot
ExecStart=-{put your script location here}start_BCM20702A0.sh
[Install]
WantedBy=basic.target
WantedBy=suspend.target
WantedBy=hibernate.target
Enable it via
systemctl enable loadfw.service
and bazinga - the firmware gets loaded at every boot, suspend and hibernate.
Harvey
Linux is like a wigwam: No Gates, no Windows and an Apache inside
Offline
I made a few changes as bluetooth was softblocked after boot. rfkill is required.
pacman -S rfkill
The modified script checks to see if adapter is soft blocked. Only one of the checks is necessary (probably), but I put two in just in case. One before the firmware is uploaded and one after.
I also made a few more changes to both the service file and the script, so that it is easier to use multiple devices.
Script: (no longer assuming anything, so the vendorID, deviceID, and the hci location can be specified. Useful for systems with multiple bluetooth?)
#!/bin/bash
#
# BCM20702A0 BT Adapter upload rampatch
# env Variables
logfile=/var/log/rampatch.log
# logfile check
if ! test -f ${logfile} ; then
# logfile does not exist, so create it
touch $logfile
fi
echo "-------------------------------------------------------" >> $logfile
entrytime=$(date +"%Y-%m-%d %H:%M:%S")
echo $entrytime " applying rampatch to BCM20702A0 bluetooth adapter" >> $logfile
if [ ! "$1" ] || [ ! "$2" ] || [ ! "$3" ]; then
echo "Not enough arguments passed." >> $logfile
echo "Not enough arguments passed."
echo "Usage: $0 <vendorID> <deviceID> <deviceLocation>" >> $logfile
echo "Usage: $0 <vendorID> <deviceID> <deviceLocation>"
exit 1
fi
vendorID=$1
deviceID=$2
deviceLocation=$3
# wait for hci0 to become available and usable
sleep 1
# Just in case bluetooth is softblocked (before patch)
RFKILLSOFT=$(rfkill list | grep Bluetooth -n2 | grep Soft | grep yes)
if [ "$RFKILLSOFT" ]; then
echo "Bluetooth was soft disabled before applying patch" >> $logfile
rfkill unblock bluetooth >> $logfile
hciconfig $deviceLocation reset >> $logfile
fi
/usr/bin/brcm_patchram_plus_usb --patchram /lib/firmware/fw-${vendorID}_${deviceID}.hcd $deviceLocation >> $logfile
# Just in case something happened and its blocked after uploading the patch
RFKILLSOFT=$(rfkill list | grep Bluetooth -n2 | grep Soft | grep yes)
if [ "$RFKILLSOFT" ]; then
echo "Bluetooth was soft disabled (after patch)" >> $logfile
rfkill unblock bluetooth >> $logfile
hciconfig $deviceLocation reset >> $logfile
fi
entrytime=$(date +"%Y-%m-%d %H:%M:%S")
echo $entrytime " ..done" >> $logfile
echo "-------------------------------------------------------" >> $logfile
systemD unit: (just edited to use the modified script).
[Unit]
Description=Load firmware into BCM20702A0 bluetooth USB adapter
After=basic.target
After=suspend.target
After=hibernate.target
[Service]
Type=oneshot
ExecStart=/usr/bin/start_BCM20702A0.sh 0489 e031 hci0
[Install]
WantedBy=basic.target
WantedBy=suspend.target
WantedBy=hibernate.target
Gnome's Bluetooth control can't see it, but that might be BlueZ.
hcitool scan
can see devices just fine.
EDIT: modified script so that it can accept arguments. It doesn't check the validity of the arguments, but it outputs to both log file and command line (for people testing). Also modified systemd service file with the arguments.
Last edited by vorpalblade (2013-12-17 17:40:26)
Offline