How to hotswap the UltraBase
Contents
Introduction
Here is how I set up an X22 to allow hot ejection/removal of the ultrabase. See also this related page for the UltraBay. These instructions are well-tested, but ymmv.
Features
- Uses lt_hotswap to preserve DMA on re-insert
- Idiot-proof (somewhat)
- Scripts also work without lt_hotswap (using the older way, idectl).
- Makes use of ThinkPad beeps to inform user.
System
- X22 thinkpad + ultrabase + DVD-R
- lt_hotswap version 0.3.9
- kernel-2.6.17.1
- xorg 6.9.0
Files
rc.local
First, make sure the lt_hotswap module is loaded. Add this to /etc/rc.local (or use modprobe.preload, if you prefer)
echo "Loading lt_hotswap module" modprobe lt_hotswap hdc_dock=1
/etc/acpi/events/lths
Disable the existing lths script. Here is the modified /etc/acpi/events/lths:
# Call the LTHS script event=lths.* #action=/usr/local/sbin/lths.sh %e action=echo "Not invoking lths.sh; this is now done by the ultrabase_eject and insert scripts instead."
/etc/acpi/events/ultrabase_eject
Respond to an ultrabase eject event. Here is /etc/acpi/events/ultrabase_eject
#Ultrabase eject button has been pressed #We can be triggered by an ibm/bay event if NOT using lt_hotswap, or an lt_hotswap event if we are. event=ibm/bay.MSTR.00000003.00000000 event=lths.MSTR.00000003.00000000 action=/etc/acpi/actions/ultrabase_eject.sh
/etc/acpi/events/ultrabase_insert
Respond to an ultrabase insert event. Here is /etc/acpi/events/ultrabase_insert
#Ultrabase has been re-inserted #We can be triggered by an ibm/bay event if NOT using lt_hotswap, or an lt_hotswap event if we are. event=ibm/bay.MSTR.00000001.00000000 event=lths.MSTR.00000001.00000000 action=/etc/acpi/actions/ultrabase_insert.sh
/etc/acpi/actions/ultrabase_eject.sh
This is the actual script which does the ejection. It is /etc/acpi/actions/ultrabase_eject.sh
- Note the dependency on cddb-id.
This page contains a large amount of code. The actual code should be moved to a dedicated code article, to make easier to download and edit.
#!/bin/bash echo "syncing disks for safety" sync echo "Unregistering IDE interface for CDROM and preparing to eject." #Note: the BIOS will already deal with the ultrabay LED (number 3). It will: # * turn it on when the bay is loaded # * turn it off when the bay is unloaded # * blink it when it is waiting between an eject request and an eject. (Linux never takes long enough to see this!) #What if there is a disk in the drive? #Case 1: there is an umounted CDROM, or an AudioCD/DVD which is NOT playing. # => It's OK to proceed. #Case 2: there is a mounted CDROM. # => we MUST unmount it, or give up on ejecting. if grep hdc /proc/mounts >/dev/null; then echo "There is a mounted filesystem on /dev/hdc. Trying to unmount it" umount /dev/hdc if [ $? == 0 ]; then echo "Successfully unmounted the CDROM." else echo "The CDROM is busy; can't unmount. Do not try to undock." echo 9 > /proc/acpi/ibm/beep #This is an "unhappy, warning beep" exit 1 fi fi #Case 3: there is a AudioCD/DVD which is currently playing. #How do we detect this? It could be just using cdplay (which has no associated process) #The following methd is ugly, and it requires the cddb-id program. However, it does work. #Assuming that we have already ruled out a mounted filesystem, then... CDDBID=$(cddb-id /dev/hdc 2>/dev/null) if [ -n "$CDDBID" ]; then echo "There is a CD in the drive. Ejecting it" eject /dev/hdc #Buglet: we don't necessarily want to eject the disk; we just want to be sure it has stopped playing. fi #We're now OK to proceed. if /sbin/lsmod | grep lt_hotswap > /dev/null ; then echo "We are using lt_hotswap" #Eject the bay using lths. echo -n "MSTR eject" > /proc/acpi/lths else echo "We are not using lt_hotswap. Do it the old way with idectl." #Unregister IDE interface 1. This WILL cause a kernel panic if there is anything in the drive! idectl 1 off #Tell the thinkpad the bay is to be ejected echo eject > /proc/acpi/ibm/bay fi #Beep happily echo 6 > /proc/acpi/ibm/beep echo "OK to undock"
/etc/acpi/actions/ultrabase_insert.sh
This script is called on insertion. It is /etc/acpi/actions/ultrabase_insert.sh
#!/bin/bash echo "Ultrabase has been inserted. Re-registering IDE interface for CDROM." if /sbin/lsmod | grep lt_hotswap > /dev/null ; then echo "We are using lt_hotswap" echo "Enabling DMA on /dev/hdc" hdparm -d 1 -u 1 -c 1 /dev/hdc #LTHS already beeps; no beep required here. else echo "We are not using lt_hotswap. Do it the old way with idectl." #Register IDE interface 1 idectl 1 rescan #Turn DMA on again. But this is probably a vain attempt; it will fail unless we are using lt_hotswap. sleep 2 hdparm -d1 /dev/hdc || echo "WARNING: DMA cannot be re-enabled for hdc after insert. You'll have to reboot for now." #Beep happily echo 6 > /proc/acpi/ibm/beep fi echo "Redocked successfully" echo "Note: KDE's volume manager might not work anymore with the CD/DVD drive."
Debugging
- The easiest way to check what is happening is:
tail -f /var/log/acpid
- Remember, after modifying anything in /etc/acpi/events, to reload the acpid rules:
killall -HUP acpid
- Note that stdout from all scripts ends up in /var/log/acpid. But to communicate a message with the user, it's best to use either the various thinkpad beeps, or perhaps the thinklight.
- Note: idectl and lt_hotswap really don't get along together. You will lock the system.
Usage
0) Save your files; this could (possibly) crash the kernel. 1) Press the "Request ejection" button, which is on the front of the ultrabase (located between CD drive and floppy). 2) The thinkpad should beep happily (high-low). If so, proceed. Otherwise, if it beeps unhappily (3 very short high beeps), it was unable to unmount a busy filesystem in the optical drive. 3) Gently pull the release handles (back left/right of the ultrabase). If it beeps unhappily (long, high), stop pulling. 4) Pull the handles harder to physically eject the thinkpad. 5) Later, reseat the thinkpad with a firm push.
Note: If you change your mind after the thinkpad has beeped happily at (2), you should eject the laptop, and then re-insert.