Difference between revisions of "How to hotswap the UltraBase"
RichardNeill (Talk | contribs) |
(→Usage) |
||
(13 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
== Introduction == | == Introduction == | ||
− | Here is how I set up an {{X22}} to allow hot ejection/removal of the | + | Here is how I set up an {{X22}} to allow hot ejection/removal of the UltraBase. See also [[How_to_hotswap_Ultrabay_devices|this related page]] for the Ultrabay. These instructions are well-tested, but ymmv. |
===Features=== | ===Features=== | ||
− | * Uses lt_hotswap to preserve DMA on re-insert | + | * Uses <tt>lt_hotswap</tt> to preserve DMA on re-insert |
− | * Idiot-proof ( | + | * Idiot-proof (somewhat) |
+ | * Scripts also work without <tt>lt_hotswap</tt> (using the older way, <tt>idectl</tt>). | ||
+ | * Makes use of ThinkPad beeps to inform user. | ||
===System=== | ===System=== | ||
− | * X22 | + | * X22 ThinkPad + UltraBase + DVD-R |
* [[lt_hotswap]] version 0.3.9 | * [[lt_hotswap]] version 0.3.9 | ||
* kernel-2.6.17.1 | * kernel-2.6.17.1 | ||
Line 51: | Line 53: | ||
This is the actual script which does the ejection. It is /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'''. | ||
+ | {{MoveToCode}} | ||
#!/bin/bash | #!/bin/bash | ||
Line 58: | Line 62: | ||
echo "Unregistering IDE interface for CDROM and preparing to eject." | echo "Unregistering IDE interface for CDROM and preparing to eject." | ||
− | #Note: the BIOS will already deal with the ultrabay LED (number 3). It will | + | #Note: the BIOS will already deal with the ultrabay LED (number 3). It will: |
− | # turn it on when the bay is loaded | + | # * turn it on when the bay is loaded |
− | # turn it off when the bay is unloaded | + | # * 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!) | + | # * 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? | #What if there is a disk in the drive? | ||
#Case 1: there is an umounted CDROM, or an AudioCD/DVD which is NOT playing. | #Case 1: there is an umounted CDROM, or an AudioCD/DVD which is NOT playing. | ||
# => It's OK to proceed. | # => It's OK to proceed. | ||
− | #Case 2: there is a mounted CDROM. | + | #Case 2: there is a mounted CDROM. |
+ | # => we MUST unmount it, or give up on ejecting. | ||
if grep hdc /proc/mounts >/dev/null; then | if grep hdc /proc/mounts >/dev/null; then | ||
echo "There is a mounted filesystem on /dev/hdc. Trying to unmount it" | echo "There is a mounted filesystem on /dev/hdc. Trying to unmount it" | ||
Line 79: | Line 84: | ||
fi | fi | ||
fi | fi | ||
− | + | ||
− | #Case 3: there is a AudioCD/DVD which is currently playing. | + | #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 process) | + | #How do we detect this? It could be just using cdplay (which has no associated process) |
− | #Assuming that we have already ruled out a mounted filesystem, then... | + | #The following methd is ugly, and it requires the cddb-id program. However, it does work. |
− | CDDBID=$(cddb-id /dev/hdc 2>/dev/null) | + | #Assuming that we have already ruled out a mounted filesystem, then... |
− | if [ -n "$CDDBID" ]; then | + | CDDBID=$(cddb-id /dev/hdc 2>/dev/null) |
+ | if [ -n "$CDDBID" ]; then | ||
echo "There is a CD in the drive. Ejecting it" | echo "There is a CD in the drive. Ejecting it" | ||
− | eject /dev/hdc | + | 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 | |
− | |||
− | if /sbin/lsmod | grep lt_hotswap > /dev/null ; then | ||
echo "We are using lt_hotswap" | echo "We are using lt_hotswap" | ||
− | + | #Eject the bay using lths. | |
− | |||
echo -n "MSTR eject" > /proc/acpi/lths | echo -n "MSTR eject" > /proc/acpi/lths | ||
− | + | else | |
− | else | ||
echo "We are not using lt_hotswap. Do it the old way with idectl." | 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 | idectl 1 off | ||
− | + | #Tell the thinkpad the bay is to be ejected | |
− | |||
echo eject > /proc/acpi/ibm/bay | echo eject > /proc/acpi/ibm/bay | ||
− | + | fi | |
− | fi | + | |
− | + | #Beep happily | |
− | #Beep happily | + | echo 6 > /proc/acpi/ibm/beep |
− | echo 6 > /proc/acpi/ibm/beep | + | echo "OK to undock" |
− | |||
− | echo "OK to undock" | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
===/etc/acpi/actions/ultrabase_insert.sh=== | ===/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." | |
− | + | ||
− | #!/bin/bash | + | if /sbin/lsmod | grep lt_hotswap > /dev/null ; then |
− | 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 "We are using lt_hotswap" | ||
echo "Enabling DMA on /dev/hdc" | echo "Enabling DMA on /dev/hdc" | ||
hdparm -d 1 -u 1 -c 1 /dev/hdc | hdparm -d 1 -u 1 -c 1 /dev/hdc | ||
− | + | ||
#LTHS already beeps; no beep required here. | #LTHS already beeps; no beep required here. | ||
− | else | + | else |
echo "We are not using lt_hotswap. Do it the old way with idectl." | echo "We are not using lt_hotswap. Do it the old way with idectl." | ||
− | + | ||
#Register IDE interface 1 | #Register IDE interface 1 | ||
idectl 1 rescan | idectl 1 rescan | ||
− | + | #Turn DMA on again. But this is probably a vain attempt; it will fail unless we are using lt_hotswap. | |
− | #Turn DMA on again. But this is a vain attempt; it will fail unless we | ||
sleep 2 | sleep 2 | ||
hdparm -d1 /dev/hdc || echo "WARNING: DMA cannot be re-enabled for hdc after insert. You'll have to reboot for now." | hdparm -d1 /dev/hdc || echo "WARNING: DMA cannot be re-enabled for hdc after insert. You'll have to reboot for now." | ||
− | + | ||
#Beep happily | #Beep happily | ||
echo 6 > /proc/acpi/ibm/beep | echo 6 > /proc/acpi/ibm/beep | ||
− | fi | + | 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== | ||
− | + | # Save your files; this could (possibly) crash the kernel. | |
− | + | # Press the "Request ejection" button, which is on the front of the ultrabase (located between CD drive and floppy). | |
− | The | + | # 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. <br>Note: If you change your mind after the thinkpad has beeped happily, you should eject the laptop, and then re-insert. |
− | + | # Gently pull the release handles (back left/right of the ultrabase). If it beeps unhappily (long, high), stop pulling. | |
− | + | # Pull the handles harder to physically eject the thinkpad. | |
− | + | # Later, reseat the thinkpad with a firm push. | |
− | |||
− | |||
− | |||
− | the |
Latest revision as of 01:46, 1 March 2010
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
- Save your files; this could (possibly) crash the kernel.
- Press the "Request ejection" button, which is on the front of the ultrabase (located between CD drive and floppy).
- 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. - Gently pull the release handles (back left/right of the ultrabase). If it beeps unhappily (long, high), stop pulling.
- Pull the handles harder to physically eject the thinkpad.
- Later, reseat the thinkpad with a firm push.