usb_gadget 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #!/bin/sh
  2. #set -xv
  3. SELF=${SELF:-$(basename $0)}
  4. source /usr/local/lib/utils
  5. # The composite gadget directory
  6. GADGET=/sys/kernel/config/usb_gadget/FunKey
  7. # Check if Ethernet over USB network is requested
  8. [ ! -f /mnt/usbnet ]
  9. USBNET=${?}
  10. # USB VID for Linux Foundation
  11. ID_VENDOR="0x1d6b"
  12. # USB PID for Multifunction Composite Gadget
  13. ID_PRODUCT="0x0104"
  14. # Get the CPU serial number
  15. SERIAL="$(grep Serial /proc/cpuinfo | sed 's/Serial\s*: \(\w*\)/\1/')"
  16. # Build a MAC address from it
  17. MAC="$(echo ${SERIAL} | sed 's/\(\w\w\)/:\1/g' | cut -b 2-)"
  18. # Derive host and device MAC addresses
  19. MAC_HOST="12$(echo ${MAC} | cut -b 3-)"
  20. MAC_DEV="02$(echo ${MAC} | cut -b 3-)"
  21. # Initialize the USB gadget
  22. init_usb_gadget() {
  23. # Don't proceed if existing gadget is present
  24. if [ -e ${GADGET} ]; then
  25. return 0
  26. fi
  27. # Get the legacy drivers out of the way
  28. modprobe -r g_ether
  29. modprobe -r g_mass_storage
  30. # Load the libcomposite USB driver
  31. modprobe libcomposite
  32. # USB Device Controller Driver
  33. local udc_driver=$(ls /sys/class/udc | cut -f1 | head -n 1)
  34. # Create our gadget directory
  35. mkdir ${GADGET}
  36. mkdir ${GADGET}/strings/0x409
  37. mkdir ${GADGET}/configs/FunKey.1
  38. mkdir ${GADGET}/configs/FunKey.1/strings/0x409
  39. test ${USBNET} -eq 1 && mkdir ${GADGET}/functions/rndis.usb0
  40. mkdir ${GADGET}/functions/mass_storage.mmcblk0p4
  41. # USB2
  42. echo "0x0200" > ${GADGET}/bcdUSB
  43. # Communication Device Class
  44. if [ ${USBNET} -eq 1 ]; then
  45. echo "0x02" > ${GADGET}/bDeviceClass
  46. echo "0x00" > ${GADGET}/bDeviceSubClass
  47. fi
  48. # USB VID and PID
  49. echo ${ID_VENDOR} > ${GADGET}/idVendor
  50. echo ${ID_PRODUCT} > ${GADGET}/idProduct
  51. # Device Release Number
  52. echo "0x0100" > ${GADGET}/bcdDevice
  53. # Device String Descriptiors
  54. echo "FunKey" > ${GADGET}/strings/0x409/manufacturer
  55. echo "FunKey S" > ${GADGET}/strings/0x409/product
  56. echo ${SERIAL} > ${GADGET}/strings/0x409/serialnumber
  57. # Turn on "OS Descriptors" support for RNDIS
  58. if [ ${USBNET} -eq 1 ]; then
  59. echo 1 > ${GADGET}/os_desc/use
  60. echo "0xcd" > ${GADGET}/os_desc/b_vendor_code
  61. echo "MSFT100" > ${GADGET}/os_desc/qw_sign
  62. fi
  63. # Configuration
  64. # Maximum power is 500 mA
  65. echo 500 > ${GADGET}/configs/FunKey.1/MaxPower
  66. # Configuration String Descriptors
  67. if [ ${USBNET} -eq 1 ]; then
  68. echo "Mass Storage + RNDIS" > ${GADGET}/configs/FunKey.1/strings/0x409/configuration
  69. else
  70. echo "Mass Storage" > ${GADGET}/configs/FunKey.1/strings/0x409/configuration
  71. fi
  72. if [ ${USBNET} -eq 1 ]; then
  73. # Make the FunKey.1 configuration the one associated with OS Descriptors
  74. ln -s ${GADGET}/configs/FunKey.1 ${GADGET}/os_desc
  75. # RNDIS Function
  76. # Host & Device MAC Addresses
  77. echo ${MAC_HOST} > ${GADGET}/functions/rndis.usb0/host_addr
  78. echo ${MAC_DEV} > ${GADGET}/functions/rndis.usb0/dev_addr
  79. # Compatible ID & Sub-Compatible ID
  80. echo "RNDIS" > ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/compatible_id
  81. echo "5162001" > ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/sub_compatible_id
  82. # Add the "Icons" Extended Property
  83. mkdir ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/Icons
  84. echo 2 > ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/Icons/type
  85. echo "%SystemRoot%\\system32\\shell32.dll,-233" > ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/Icons/data
  86. # Add the "Label" Extended Property
  87. mkdir ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/Label
  88. echo 1 > ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/Label/type
  89. echo "FunKey S Device" > ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/Label/data
  90. fi
  91. # Mass Storage Function
  92. # Backing Store file
  93. #echo "/dev/mmcblk0p4" > ${GADGET}/functions/mass_storage.mmcblk0p4/lun.0/file
  94. # Gadget is not allowed to halt bulk endpoints
  95. echo 0 > ${GADGET}/functions/mass_storage.mmcblk0p4/stall
  96. # Do not simulate a CDROM
  97. echo 0 > ${GADGET}/functions/mass_storage.mmcblk0p4/lun.0/cdrom
  98. # No SCSI Force Unit Access (FUA) to work in synchronous mode ?!?
  99. echo 0 > ${GADGET}/functions/mass_storage.mmcblk0p4/lun.0/nofua
  100. # LUN is removable
  101. echo 1 > ${GADGET}/functions/mass_storage.mmcblk0p4/lun.0/removable
  102. # Inquiry String
  103. echo "FunKey S Shared Disk" > ${GADGET}/functions/mass_storage.mmcblk0p4/lun.0/inquiry_string
  104. if [ ${USBNET} -eq 1 ]; then
  105. # Add the RNDIS function to the FunKey.1 configuration
  106. ln -s ${GADGET}/functions/rndis.usb0 ${GADGET}/configs/FunKey.1
  107. # Bind the USB Gadget as RNDIS device
  108. echo ${udc_driver} > ${GADGET}/UDC
  109. sleep 5
  110. # Start network services
  111. systemctl start networking ntp dropbear > /dev/null 2>&1
  112. # Unbind the device
  113. echo > ${GADGET}/UDC
  114. fi
  115. # Add the Mass Storage function to the FunKey.1 configuration
  116. ln -s ${GADGET}/functions/mass_storage.mmcblk0p4 ${GADGET}/configs/FunKey.1
  117. # Each interface specifies its own class code
  118. echo "0x00" > ${GADGET}/bDeviceClass
  119. # Bind the USB Gadget as a Mass Storage device
  120. echo ${udc_driver} > ${GADGET}/UDC
  121. return 0
  122. }
  123. # Deinitialize the USB gadget
  124. deinit_usb_gadget() {
  125. # Unbind the device
  126. echo > ${GADGET}/UDC
  127. # Remove functions from configurations
  128. rm ${GADGET}/configs/FunKey.1/mass_storage.mmcblk0p4
  129. if [ ${USBNET} -eq 1 ]; then
  130. rm ${GADGET}/configs/FunKey.1/rndis.usb0
  131. fi
  132. # Remove string directories in configurations
  133. rmdir ${GADGET}/configs/FunKey.1/strings/0x409
  134. # Remove configurations from OS descriptors
  135. if [ ${USBNET} -eq 1 ]; then
  136. rm ${GADGET}/os_desc/FunKey.1
  137. fi
  138. # Remove configurations
  139. rmdir ${GADGET}/configs/FunKey.1
  140. # Remove extended properties from OS descriptors
  141. if [ ${USBNET} -eq 1 ]; then
  142. rmdir ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/Icons
  143. rmdir ${GADGET}/functions/rndis.usb0/os_desc/interface.rndis/Label
  144. fi
  145. # Remove functions
  146. rmdir ${GADGET}/functions/mass_storage.mmcblk0p4
  147. if [ ${USBNET} -eq 1 ]; then
  148. rmdir ${GADGET}/functions/rndis.usb0
  149. fi
  150. # Remove strings
  151. rmdir ${GADGET}/strings/0x409
  152. # Finallyy remove the gadget
  153. rmdir ${GADGET}
  154. # Unload the kernel modules
  155. modprobe -r usb_f_mass_storage usb_f_rndis
  156. }