| #!/bin/sh |
| |
| setup_image() |
| { |
| set -x |
| local storage="$1" |
| local sz_mb="$2" |
| # create the backing store |
| dd if=/dev/zero of="$storage" bs=1M seek="$sz_mb" count=0 2>/dev/null |
| # this shows up as 23FC-F676 in /dev/disk/by-uuid |
| local diskid=0x23FCF676 |
| mkdosfs -n 'OPENBMC-FW' -i $diskid -I "$storage" >/dev/null 2>&1 |
| } |
| |
| mount_image() |
| { |
| set -x |
| local storage="$1" |
| local stormnt="$2" |
| mkdir -p $stormnt || exit 1 |
| mount -o loop -t vfat "$storage" "$stormnt" |
| } |
| |
| cleanup_image() |
| { |
| set -x |
| local storage="$1" |
| local stormnt="$2" |
| umount -f "$stormnt" |
| rm -f "$storage" |
| rmdir "$stormnt" |
| } |
| |
| ecm() |
| { |
| set -x |
| local name="$1" |
| local on="$2" |
| if [ "$on" = "on" ]; then |
| usb_insert "${name}" ecm |
| elif [ "$on" = "off" ]; then |
| usb_eject "${name}" ecm |
| else |
| echo "Unknown ecm command" |
| usage |
| fi |
| } |
| |
| GADGET_BASE=/sys/kernel/config/usb_gadget |
| |
| which_dev() |
| { |
| local in_use="$(cat $GADGET_BASE/*/UDC)" |
| cd /sys/class/udc |
| for D in *; do |
| case "$in_use" in |
| *"$D"*) ;; |
| *) echo "$D"; return 0;; |
| esac |
| done |
| return 1 |
| } |
| |
| usb_ms_insert() |
| { |
| usb_insert "$1" mass_storage "$2" "$3" |
| } |
| |
| usb_ms_eject() |
| { |
| usb_eject "$1" mass_storage |
| } |
| |
| ## $1: device syspath to provide usb-gadget configure, |
| ## e.g. functions/mass_storage.usb0/lun.0/ |
| ## |
| ## $2: optional usb gadget interface type, e.g. usb|usb-ro|hdd|cdrom. |
| ## if $2 not specified or illegal, then using 'usb-ro' as default |
| usb_set_interface_type() |
| { |
| local usb_gadget_syspath="$1" |
| local interface_type="${2:-'usb-ro'}" |
| |
| # defining target variables to configure interface type |
| local removable= |
| local ro= |
| local cdrom= |
| |
| if [ ! -d ${usb_gadget_syspath} ]; then |
| echo "Device syspath ${usb_gadget_syspath} does not exist" >&2 |
| return 1 |
| fi |
| |
| case "${interface_type}" in |
| hdd) |
| removable=0 |
| ro=0 |
| cdrom=0 |
| ;; |
| usb) |
| removable=1 |
| ro=0 |
| cdrom=0 |
| ;; |
| |
| cdrom) |
| removable=1 |
| ro=1 |
| cdrom=1 |
| ;; |
| usb-ro) |
| removable=1 |
| ro=1 |
| cdrom=0 |
| ;; |
| *) |
| echo "No mass-storage interface type specified or illegal" >&2 |
| echo "Configuring interface type to 'usb-ro'" >&2 |
| removable=1 |
| ro=1 |
| cdrom=0 |
| ;; |
| esac |
| |
| echo $removable > ${usb_gadget_syspath}removable |
| echo $ro > ${usb_gadget_syspath}ro |
| echo $cdrom > ${usb_gadget_syspath}cdrom |
| } |
| |
| ## $1: device name, e.g. usb0, usb1 |
| ## $2: device type defined in kernel, e.g. mass_storage, ecm |
| ## $3: optional storage file, e.g. /dev/nbd1, /tmp/boot.iso |
| ## $4: optional mass storage interface type, e.g. usb|usb-ro|hdd|cdrom. |
| ## if interface type not specified then using 'usb-ro' as default |
| usb_insert() |
| { |
| local name="$1" |
| local dev_type="$2" |
| local storage="$3" |
| local interface_type="${4:-'usb-ro'}" |
| |
| if [ -d $GADGET_BASE/"${name}" ]; then |
| echo "Device ${name} already exists" >&2 |
| return 1 |
| fi |
| mkdir $GADGET_BASE/"${name}" |
| cd $GADGET_BASE/"${name}" |
| |
| echo 0x1d6b > idVendor # Linux Foundation |
| echo 0x0105 > idProduct # FunctionFS Gadget |
| mkdir strings/0x409 |
| local machineid=$(cat /etc/machine-id) |
| local data="OpenBMC USB gadget device serial number" |
| local serial=$( echo -n "${machineid}${data}${machineid}" | \ |
| sha256sum | cut -b 0-12 ) |
| echo $serial > strings/0x409/serialnumber |
| echo OpenBMC > strings/0x409/manufacturer |
| echo "OpenBMC USB Device" > strings/0x409/product |
| |
| mkdir configs/c.1 |
| mkdir functions/"${dev_type}"."${name}" |
| if [ "${dev_type}" = "mass_storage" ]; then |
| echo "${storage}" > "functions/${dev_type}.${name}/lun.0/file" |
| usb_set_interface_type \ |
| "functions/${dev_type}.${name}/lun.0/" "${interface_type}" |
| fi |
| mkdir configs/c.1/strings/0x409 |
| |
| echo "Conf 1" > configs/c.1/strings/0x409/configuration |
| echo 120 > configs/c.1/MaxPower |
| ln -s functions/"${dev_type}"."${name}" configs/c.1 |
| local dev=$(which_dev) |
| echo $dev > UDC |
| } |
| |
| ## $1: device name, e.g. usb0, usb1 |
| ## $2: device type defined in kernel, e.g. mass_storage, ecm |
| usb_eject() |
| { |
| local name="$1" |
| local dev_type="$2" |
| |
| echo '' > $GADGET_BASE/"${name}"/UDC |
| |
| rm -f $GADGET_BASE/"${name}"/configs/c.1/"${dev_type}"."${name}" |
| rmdir $GADGET_BASE/"${name}"/configs/c.1/strings/0x409 |
| rmdir $GADGET_BASE/"${name}"/configs/c.1 |
| rmdir $GADGET_BASE/"${name}"/functions/"${dev_type}"."${name}" |
| rmdir $GADGET_BASE/"${name}"/strings/0x409 |
| rmdir $GADGET_BASE/"${name}" |
| } |
| |
| usage() |
| { |
| echo "Usage: $0 <action> ..." |
| echo " $0 setup <file> <sizeMB>" |
| echo " $0 insert <name> <file> [<type=usb|usb-ro|hdd|cdrom>]" |
| echo " $0 eject <name>" |
| echo " $0 mount <file> <mnt>" |
| echo " $0 cleanup <file> <mnt>" |
| echo " $0 ecm <name> <on|off>" |
| exit 1 |
| } |
| |
| echo "$#: $0 $@" |
| case "$1" in |
| insert) |
| shift |
| usb_ms_insert "$@" |
| ;; |
| eject) |
| shift |
| usb_ms_eject "$@" |
| ;; |
| setup) |
| shift |
| setup_image "$@" |
| ;; |
| mount) |
| shift |
| mount_image "$@" |
| ;; |
| cleanup) |
| shift |
| cleanup_image "$@" |
| ;; |
| ecm) |
| shift |
| ecm "$@" |
| ;; |
| *) |
| usage |
| ;; |
| esac |
| exit $? |