Tiny Core Extensions > TCE Q&A Forum

how do firmware extensions work without startup script?

<< < (5/10) > >>

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