Tiny Core Extensions > TCE Q&A Forum
how do firmware extensions work without startup script?
Rich:
Hi GNUser
I did some playing around and came up with this:
--- Code: ---#!/bin/sh
Debug="test"
# Uncomment the next line to turn on debugging messages.
Debug="echo"
# Vendor ID and product ID (8644:8003).
VID="8644"
PID="8003"
# Find the modalias file that contains our VID and PID.
MODALIS="$(find /sys -name modalias | xargs grep "v""$VID""p""$PID" 2> /dev/null)"
if [ -n "$MODALIS" ]
then
"$Debug" "$MODALIS"
# Grab the path to modalias.
UEVENT="${MODALIS%/*}"
# Grab the device designation from the end of the path.
DEVICE="${UEVENT##*/}"
# Complete path to uevent file.
UEVENT="$UEVENT""/uevent"
"$Debug" "DEVICE=$DEVICE"
"$Debug" "UEVENT=$UEVENT"
fi
if [ -f "$UEVENT" ]
then
# Grab the driver name from uevent file.
DRIVER="$(grep "DRIVER" $UEVENT | cut -d '=' -f2)"
"$Debug" "DRIVER=$DRIVER"
fi
if [ -n "$DRIVER" ]
then
# Find the directory named for the driver.
BINDPATH="$(find /sys -type d -name "$DRIVER")"
# That directory should contain the unbind and bind files.
BINDFILE="$BINDPATH""/bind"
UNBINDFILE="$BINDPATH""/unbind"
"$Debug" "BINDPATH=$BINDPATH"
"$Debug" "BINDFILE=$BINDFILE"
"$Debug" "UNBINDFILE=$UNBINDFILE"
fi
if [ -e "$UNBINDFILE" ]
then
# Remove device.
echo "$DEVICE" | sudo tee "$UNBINDFILE" 1> /dev/null
fi
"$Debug" "Sleep ..."
sleep 3
"$Debug" "... Wake up"
if [ -e "$BINDFILE" ]
then
# Add device back.
echo "$DEVICE" | sudo tee "$BINDFILE" 1> /dev/null
fi
--- End code ---
I don't have any USB Wifi devices, but I tested it with a thumb drive.
I did observe remove and add events using udevadm monitor.
Set the VID and PID variables to match your wifi device.
A copy of the script is attached. Ask questions if something is not clear.
GNUser:
Hi, Rich. Thank you very much for the script.
Here is lsusb output for context:
--- Code: ---bruno@x230:~$ lsusb
...
Bus 002 Device 003: ID 040d:3801 VIA Technologies, Inc.
...
--- End code ---
Unfortunately, the script fails here:
--- Code: ---MODALIS="$(find /sys -name modalias | xargs grep "v""$VID""p""$PID" 2> /dev/null)"
--- End code ---
Because the two relevant files for my usb device are these (notice no "modalias" in the name)...
--- Code: ---/sys/devices/pci0000:00/0000:00:1a.0/usb2/2-1/2-1.2/uevent
/sys/devices/pci0000:00/0000:00:1a.0/usb2/2-1/2-1.2/idProduct
--- End code ---
...and they do not contain anything like v$VIDp$PID:
--- Code: ---$ sudo cat /sys/devices/pci0000:00/0000:00:1a.0/usb2/2-1/2-1.2/uevent
MAJOR=189
MINOR=130
DEVNAME=bus/usb/002/003
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=40d/3801/108
TYPE=255/255/255
BUSNUM=002
DEVNUM=003
$ sudo cat /sys/devices/pci0000:00/0000:00:1a.0/usb2/2-1/2-1.2/idProduct
3801
--- End code ---
Also, notice how VID is 040d but the uevent file contains 40d (missing leading zero). Why, oh why?
Anyway, inspired by your script, I created this variation...
--- Code: ---#!/bin/sh
productId=3801 # get this from lsusb
productFile=$(find /sys -name 'idProduct' | xargs grep -l "$productId" 2>/dev/null)
device=$(basename $(dirname $productFile)) # e.g., device=2-1.2
sudo sh -c "echo $device >/sys/bus/usb/drivers/usb/unbind 2>/dev/null"
sudo sh -c "echo $device >/sys/bus/usb/drivers/usb/bind"
--- End code ---
...and it's working great:
--- Code: ---$ ifconfig -a wlan1
ifconfig: wlan1: error fetching interface information: Device not found
$ tce-load -i firmware-atheros
firmware-atheros.tcz: OK
$ ./USBReset.sh # instead of manually detaching+reattaching the device
$ ifconfig -a wlan1
wlan1 Link encap:Ethernet HWaddr 00:12:7B:20:6B:A0
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
--- End code ---
Thanks for pointing me in the right direction with this!
Rich:
Hi GNUser
Thanks for testing and the feedback.
--- Quote from: GNUser on September 01, 2024, 03:55:46 PM --- ... (notice no "modalias" in the name)...
--- End quote ---
I guess not all devices have aliases assign to them.
--- Quote --- ... Also, notice how VID is 040d but the uevent file contains 40d (missing leading zero). Why, oh why? ...
--- End quote ---
Now that you mention it, I recall running into that a couple of years ago.
--- Quote --- ... Anyway, inspired by your script, I created this variation...
--- End quote ---
A couple of notes:
1. idProduct is not unique if not coupled with idVendor.
2. Your search of the /sys dir may not be deep enough, possibly
resetting the hub instead of the port.
--- Quote --- ... and it's working great: ...
--- End quote ---
Hey, no fair. That's what I was shooting for. ;D
Anyway, I reworked my script:
--- Code: ---#!/bin/sh
Debug="test"
# Uncomment the next line to turn on debugging messages.
Debug="echo"
# Vendor ID and product ID (8644:8003).
VID="8644"
PID="8003"
# Strips leading zeros from variable. If variable is all
# zeros, variable will be set to a single zero.
while [ ${#VID} -gt 1 ] # ${#VID} returns string length of variable.
do
# If first character of variable is not "0", end loop.
[ ${VID:0:1} != "0" ] && break
# Remove first character from variable.
VID="${VID:1}"
done
# Strips leading zeros from variable. If variable is all
# zeros, variable will be set to a single zero.
while [ ${#PID} -gt 1 ] # ${#PID} returns string length of variable.
do
# If first character of variable is not "0", end loop.
[ ${PID:0:1} != "0" ] && break
# Remove first character from variable.
PID="${PID:1}"
done
# Find the modalias file that contains our VID and PID.
UEVENTS="$(find /sys -name uevent | xargs grep "$VID""/""$PID" 2> /dev/null)"
if [ -n "$UEVENTS" ]
then
# Grab the last entry from $UEVENTS.
for UEVENT in $UEVENTS
do
UEVENT="$UEVENT"
done
"$Debug" "UEVENT=$UEVENT"
# Complete path to uevent file after stripping from :PRODUCT to end of line.
UEVENT="${UEVENT%:PRODUCT*}"
# Strip uevent file name from path.
DEVICE="${UEVENT%/*}"
"$Debug" "DEVICE=$DEVICE"
# Grab the device designation from the end of the path.
DEVICE="${DEVICE##*/}"
"$Debug" "UEVENT=$UEVENT"
"$Debug" "DEVICE=$DEVICE"
fi
if [ -f "$UEVENT" ]
then
# Grab the driver name from uevent file.
DRIVER="$(grep "DRIVER" $UEVENT | cut -d '=' -f2)"
"$Debug" "DRIVER=$DRIVER"
fi
if [ -n "$DRIVER" ]
then
# Find the directory named for the driver.
BINDPATH="$(find /sys -type d -name "$DRIVER")"
# That directory should contain the unbind and bind files.
BINDFILE="$BINDPATH""/bind"
UNBINDFILE="$BINDPATH""/unbind"
"$Debug" "BINDPATH=$BINDPATH"
"$Debug" "BINDFILE=$BINDFILE"
"$Debug" "UNBINDFILE=$UNBINDFILE"
fi
if [ -e "$UNBINDFILE" ]
then
# Remove device.
echo "$DEVICE" | sudo tee "$UNBINDFILE" 1> /dev/null
fi
"$Debug" "Sleep ..."
sleep 3
"$Debug" "... Wake up"
if [ -e "$BINDFILE" ]
then
# Add device back.
echo "$DEVICE" | sudo tee "$BINDFILE" 1> /dev/null
fi
--- End code ---
I'd appreciate if you would take this version for a spin to
see if it works any better. I've attached a copy to this post.
--- Quote --- ... Thanks for pointing me in the right direction with this!
--- End quote ---
Thanks for providing an interesting puzzle. :)
GNUser:
--- Quote from: Rich on September 02, 2024, 12:06:28 AM ---Thanks for providing an interesting puzzle. :)
--- End quote ---
Only a hacker would say such a thing :)
Your revised script gets farther but fails to set DRIVER, without which it cannot figure out the crucial UNBINDFILE and BINDFILE:
--- Code: ---$ ifconfig -a wlan1
ifconfig: wlan1: error fetching interface information: Device not found
$ tce-load -i firmware-atheros
firmware-atheros.tcz: OK
$ ./USBreset.sh
UEVENT=/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/uevent:PRODUCT=40d/3801/108
DEVICE=/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2
UEVENT=/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/uevent
DEVICE=1-1.2
DRIVER=
Sleep ...
... Wake up
$ ifconfig -a wlan1
ifconfig: wlan1: error fetching interface information: Device not found
--- End code ---
GNUser:
Hi Rich. Why not unbind+bind using the generic /sys/bus/usb/drivers/usb/unbind and /sys/bus/usb/drivers/usb/bind?
That simplifies the script because once we have DEVICE we're basically done. Here is what the script could look like with this logic plus passing VID and PID as arguments:
--- Code: ---#!/bin/sh
# Syntax: $ USBReset.sh <vendorId> <productId>
# Usage example: $ USBReset.sh
Debug="test"
# Uncomment the next line to turn on debugging messages.
Debug="echo"
# Vendor ID and product ID (e.g., 8644 8003).
VID="$1"
PID="$2"
# Strips leading zeros from variable. If variable is all
# zeros, variable will be set to a single zero.
while [ ${#VID} -gt 1 ] # ${#VID} returns string length of variable.
do
# If first character of variable is not "0", end loop.
[ ${VID:0:1} != "0" ] && break
# Remove first character from variable.
VID="${VID:1}"
done
# Strips leading zeros from variable. If variable is all
# zeros, variable will be set to a single zero.
while [ ${#PID} -gt 1 ] # ${#PID} returns string length of variable.
do
# If first character of variable is not "0", end loop.
[ ${PID:0:1} != "0" ] && break
# Remove first character from variable.
PID="${PID:1}"
done
# Find the modalias file that contains our VID and PID.
UEVENTS="$(find /sys -name uevent | xargs grep "$VID""/""$PID" 2> /dev/null)"
if [ -n "$UEVENTS" ]
then
# Grab the last entry from $UEVENTS.
for UEVENT in $UEVENTS
do
UEVENT="$UEVENT"
done
"$Debug" "UEVENT=$UEVENT"
# Complete path to uevent file after stripping from :PRODUCT to end of line.
UEVENT="${UEVENT%:PRODUCT*}"
# Strip uevent file name from path.
DEVICE="${UEVENT%/*}"
"$Debug" "DEVICE=$DEVICE"
# Grab the device designation from the end of the path.
DEVICE="${DEVICE##*/}"
"$Debug" "UEVENT=$UEVENT"
"$Debug" "DEVICE=$DEVICE"
fi
# Remove device.
echo "$DEVICE" | sudo tee /sys/bus/usb/drivers/usb/unbind >/dev/null 2>&1
"$Debug" "Sleep ..."
sleep 3
"$Debug" "... Wake up"
# Add device back.
echo "$DEVICE" | sudo tee /sys/bus/usb/drivers/usb/bind >/dev/null
--- End code ---
It works well:
--- Code: ---$ ifconfig -a wlan1
ifconfig: wlan1: error fetching interface information: Device not found
$ tce-load -i firmware-atheros
firmware-atheros.tcz: OK
$ ./USBreset.sh 040d 3801
UEVENT=/sys/devices/pci0000:00/0000:00:1a.0/usb2/2-1/2-1.2/uevent:PRODUCT=40d/3801/108
DEVICE=/sys/devices/pci0000:00/0000:00:1a.0/usb2/2-1/2-1.2
UEVENT=/sys/devices/pci0000:00/0000:00:1a.0/usb2/2-1/2-1.2/uevent
DEVICE=2-1.2
Sleep ...
... Wake up
$ ifconfig -a wlan1
wlan1 Link encap:Ethernet HWaddr 00:12:7B:20:6B:A0
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
--- End code ---
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version