Murasaki LinkStation's USB hot-plugging system

From NAS-Central Buffalo - The Linkstation Wiki
Revision as of 18:56, 27 January 2007 by 77.128.179.206 (Talk)

Jump to: navigation, search

This article Based on work by Harry, frontalot, and nix. Originally by nix. at Linkstationwiki.org

Contents

Murasaki - 'Another HotPlug'

Linux USB hot-plugging Systems
Linux hotplugging has changed often over time. While e.g. HotPlug was common in distributions based on the 2.4 kernel series, this has changed to udev in the 2.6 series. The original LS firmware, while based on a 2.4 kernel does not use HotPlug, but yet another system.


Overview

The original LinkStation firmware (at least for the LS1 and LS2) and the OpenLink firmware use a software called Murasaki for handling the USB hot-plugging of printers and hard disks. [Murasaki] is not some special Buffalo software, but a free alternative hot-plugging framework for Linux. It replaces Linux's normal hot-plugging framework HotPlug. It is unknown why Buffalo / MontaVista went for Murasaki instead of the standard hot-plugging framework. But anyhow, Murasaki is suitable for the desired task.

The Murasaki version 0.6.12 that comes with the mipsel-hdhlan LinkStation 2.05 firmware is rather old. That version also is incomplete. The components which are not used for USB hot-plugging are not included. However, the missing components, e.g. FireWire support, don't make much sense on the LinkStation and the old version is nevertheless functional.

Adding Support for Other Devices

Before you start to mess around with Murasaki, please be aware that you should possess some understanding of Murasaki, Linux, and shell scripting. In short, you should know what you are doing.

Drivers & Kernel Modules

Kernel and Modules
Just adding modules is sometimes not enough to ensure a USB device works under OpenLink. Unfortunately, some loadable modules require build-in kernel support, too. And that has often not been compiled into the stock kernel or OpenLink kernel. One example is support for USB keyboards. While the Loadable kernel modules collection contains the necessary Linux module for USB keyboards, the necessary support in the kernel is missing. One would have to build and install a new kernel to fix such problems.

Murasaki is not limited to handling only printers and hard disks. It can handle other types of USB devices too. However, the necessary drivers (kernel modules) must first be built and installed on the LinkStation. See Loadable kernel modules for information about loadable kernel modules - some of which are for USB devices.

Murasaki Configuration

Then the Murasaki configuration files need to be adapted. The Murasaki files which need to be touched are:

/etc/murasaki/murasaki.usbmap
To map devices with unknown ids to a driver.
To find out the values for an entry you should plug in the unknown USB device and then fetch the data from the syslog log file /var/log/linkstation.log. Some entries can also be found in [[1]].
/etc/murasaki/murasaki.call
To map device types or module names to corresponding start-stop scripts which are called when a device of a certain type is plugged-in or a certain module is loaded. Also, the scripts are called after a device or module is removed. :The format is
device-name script ...
for devices, or
module-name script ...
for modules. The first argument to the scripts is either start or stop to identify the actual event.
/etc/murasaki/bin/...
Start-stop scripts should be placed in /etc/murasaki/bin. The existing mount_sd.sh script in that directory can serve as an example. mount_sd.sh is the script which is supposed to mount USB disks, once they are plugged in.
/etc/murasaki/murasaki.precall
(not used by by the stock LinkStation firmware) The file has a very similar function to murasaki.call. The difference is when the scripts are called. murasaki.precall scripts are called before a device is loaded and before a device is unloaded. Scripts specified in murasaki.call are called after a device is loaded and after a device is unloaded.
/etc/murasaki/murasaki.depend
Module dependencies.
This file specifies kernel module dependencies related to USB. Typically, a USB device driver at least depends on the usbcore module. The format of an entry is
dependent: depends ...
typically an entry looks like
dependent: usbcore
/etc/murasaki/murasaki.sticky
(not used by by the stock LinkStation firmware) A list of modules which are not unloaded, even if a hot-plug remove event happens. This is useful for devices which are regularly plugged-in and out at a high frequency.


Trouble Shooting

If things don't work out, you can start debugging at the following places:

  • Check /var/log/linkstation.log for any Murasaki messages. If Murasaki doesn't know the USB ID it will print out information on how to add it here.
  • Check /proc/bus/usb/devices after inserting the USB device. There should be an entry for your device. Note, each entry for a device starts with a T line. To get a slightly better readable printout, you could run
awk '/^T/ { print ""} {print}' /proc/bus/usb/devices | more
instead of a simple cat or more.
The output for a device should, for example, look like:
T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12  MxCh= 0
D:  Ver= x.xx Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=xxxx ProdID=xxxx Rev= x.x
S:  Product=USB Storage Device
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr= 96mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
E:  Ad=81(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
Note the I (for Interface) line. A USB device can have multiple interfaces. The one is the above example has been associated with a device driver (usb-storage). This is what you want. If no interface gets associated wit a driver, it doesn't exist for the kernel.
FYI, the letters in the output stand for:
T
Topology
B
Bandwidth
D
Device description
P
Product Id
S
Text description
C
Configuration info. * indicates the active configuration.
I
Interface description
E
Endpoint descripton
  • One can check all USB drivers currently known (loaded) by the kernel with
# cat /proc/bus/usb/drivers
         usbdevfs
         hub
  0- 15: usblp
         usb-storage
         usb-storage
  • If a USB storage device has been found, and the USB storage driver been loaded, then the SCSI disk driver emulation device driver should have been automatically loaded on top of it.
cat  /proc/scsi/usb-storage-*/*
shows all such devices. E.g. the output should be similar to
   Host scsi0: usb-storage
       Vendor: xxxxx xxxx xxxxxxxxx
      Product: USB Storage Device
Serial Number: None
     Protocol: Transparent SCSI
    Transport: Bulk
         GUID: 0xxxxxxx0000000000000000
     Attached: Yes
Note the Attached: Yes line. If this doesn't say Yes, then the device has been found, but for some reason is not attached (no media in the device). However, this can also happen when an external USB hub is in use between the storage device and the LinkStation. The only known way to fix this problem with a hub is to remove the hub and connect the storage device directly.
  • If everything went fine until now, then Murasaki should have mounted the device:
# mount
...
...
/dev/sda1 on /mnt/usbdisk1 type vfat (rw)


Hacks

Supporting USB Memory Sticks and Other USB Storage Devices

mount_sd.sh on stock mipsel-hdhlan firmware refuses to mount USB memory sticks or any other USB storage device which doesn't identify itself as a hard disk or optical disk. The culprit (bug or feature?) seems to be the program /usr/bin/parse_usbscsi which is used by mount_sd.sh to identify USB disks. A potential workaround is to add the following lines to mount_sd.sh, right after the call to /usr/bin/parse_usbscsi:


#
# HACK for mounting USB memory sticks.
# The above /usr/bin/parse_usbscsi doesn't identify
# them as usable storage device.
#
awk '$1 ~ /Host/ && $3 ~ /usb-storage/ {
          printf "/dev/sd%c\n", substr($2, 5, length($2) - 5) + 97
}' /proc/scsi/usb-storage-*/* >>/mnt/usbinfo/list


Please note that this hack ignores many finer details of identifying a disk. Also, the remaining unchanged parts of the mount_sd.sh script will not only mount the found memory stick but also share it via SAMBA, AppleTalk, and provide access to the data on the stick via ftp (if any of these services is configured). This may not be desirable - depending on the data on the stick. You will also see that SAMBA and AppleTalk are restarted.

Allowing More than one USB disk

mount_sd.sh, as-delivered, just mounts the first USB disk found. This is in line with Buffalo's product description. If one feels adventurous this can be changed in mount_sd.sh. The code was originally in mount_sd.sh and has just been commented out. The commented-out sections need some minor changes to get them to work again.