How to hotswap the UltraBase

From ThinkWiki
Jump to: navigation, search

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

  1. Save your files; this could (possibly) crash the kernel.
  2. Press the "Request ejection" button, which is on the front of the ultrabase (located between CD drive and floppy).
  3. 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.
    Note: If you change your mind after the thinkpad has beeped happily, you should eject the laptop, and then re-insert.
  4. Gently pull the release handles (back left/right of the ultrabase). If it beeps unhappily (long, high), stop pulling.
  5. Pull the handles harder to physically eject the thinkpad.
  6. Later, reseat the thinkpad with a firm push.