Laptop Dell Latitude D610

From YobiWiki
Revision as of 22:35, 24 November 2010 by <bdi>PhilippeTeuwen</bdi> (talk | contribs) (Reverted edits by Etegohy (Talk) to last revision by PhilippeTeuwen)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Converted with HTML::WikiConverter::MediaWiki from my old phpwiki site


Resources

Step-by-step fresh install from the latest Debian netinstall CD:

see Laptop Dell Latitude D610 Step-by-step

Miscellaneous notes:

Kernel

  • Debian 2.6.15-1-686 with yaird version 0.0.12-3 works finally fine.
  • When you install such kernel, you could face problems running yaird as yaird requires to be run from a 2.6 kernel and Debian 2.6.8 fails booting on this sata hardware.
    Try with Debian 2.6.11
    You can also try creating the initrd from another machine with the exact same hardware because yaird uses the current hardware setup to construct the initrd image. If the root partition is different between the 2 laptops, change temporarely your /etc/fstab to mimic the one of the target laptop.
    • yaird -v -o /tmp/myinitrd linux-image-2.6.15-1-686
    • Check the log if the root partition detected by yaird seems ok
    • Move the initrd to the target computer and edit grub
  • Apparently there are less problems using initramfs-tools rather than yaird
  • cdrom
    • by default, ATAPI is disabled in the SATA driver :-(
    • echo "options libata atapi_enabled=1" > /etc/modprobe.d/libata
    • test: yaird -v -o /tmp/crap `uname -r`
      and look for the option atapi_enabled
    • dpkg-reconfigure linux-image-`uname -r`
    • If you built your own kernel with libata not as module, you have to pass to the kernel the option libata.atapi_enabled=1
  • noise
    • If you have a high sharp pitched sound coming from the laptop, try booting the kernel with the idle=halt option
  • suspend-to-ram
    • this requires a patch, see below

Harddrive

  • Smart
    • Works from kernel 2.6.15:
    • smartctl -d ata -a /dev/sda
    • Edit /etc/smartd.conf to reflect the -d ata option

X

  • use Xorg server, not XFree86!
  • To get a full-featured touchpad
    • apt-get install xfree86-driver-synaptics
    • to tune it if needed: synclient (man synaptics), synclient CircularScrolling=1 is quite cool :-)
    • check the new gsynaptics X client for on-demand tuning
  • Use this file in /etc/X11/xorg.conf or run by yourself dpkg-reconfigure xserver-xorg

Wireless

  • Go to http://ipw2200.sourceforge.net/ and download the latest firmware.
  • Unpack and move the ipw-* files to /usr/lib/hotplug/firmware.
  • With 2.6 kernels, this is not uncommon to end up with a inverted order of the interfaces, use ifrename to definitively get rid of these problems
    • echo "install ipw2200 /sbin/modprobe --ignore-install ipw2200; ifrename" >> /etc/modprobe.d/ipw2200
    • led on/off doesn't work that well
  • The card is working well with WPA, cf HostApUsage

Sound

Works out-of-the-box.
For more tuning, cf http://opensrc.org/alsa/index.php?page=intel8x0 and DebianAlsa

Saving battery and other tweaks for laptop

  • cf DebianLaptop
  • If your LID doesn't turn back on when you open it (with acpi enabled), I urge you to install vbetool and the backlight_install.sh script from DebianLaptop (select "vbepost" when prompted)
  • Hotkeys are working with the hotkey-setup package, if ou want the exact codes, cf http://gentoo-wiki.com/HARDWARE_Dell_Latitude_D610#Special_Keys

Suspend-to-ram

Finally!
This works great after having ported the following patch to the 2.6.15-7 of Debian.
I ported the patch and used the same .config as the 2.6.15-1-686 package to compile the kernel.

Here is my version, for linux-source-2.6.15 version 2.6.15-7


diff -Naur linux-source-2.6.15/drivers/scsi/ata_piix.c linux-source-2.6.15-ata/drivers/scsi/ata_piix.c
--- linux-source-2.6.15/drivers/scsi/ata_piix.c 2006-01-03 04:21:10.000000000 +0100
+++ linux-source-2.6.15-ata/drivers/scsi/ata_piix.c     2006-03-02 07:53:01.000000000 +0100
@@ -125,6 +125,8 @@
        .id_table               = piix_pci_tbl,
        .probe                  = piix_init_one,
        .remove                 = ata_pci_remove_one,
+       .suspend                = ata_pci_device_suspend,
+       .resume                 = ata_pci_device_resume,
 };

 static struct scsi_host_template piix_sht = {
@@ -145,6 +147,8 @@
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
        .ordered_flush          = 1,
+       .resume                 = ata_scsi_device_resume,
+       .suspend                = ata_scsi_device_suspend,
 };

 static const struct ata_port_operations piix_pata_ops = {
diff -Naur linux-source-2.6.15/drivers/scsi/libata-core.c linux-source-2.6.15-ata/drivers/scsi/libata-core.c
--- linux-source-2.6.15/drivers/scsi/libata-core.c      2006-01-03 04:21:10.000000000 +0100
+++ linux-source-2.6.15-ata/drivers/scsi/libata-core.c  2006-03-02 07:56:55.000000000 +0100
@@ -4099,6 +4099,104 @@
 }


+/*
+ * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
+ * without filling any other registers
+ */
+static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
+                            u8 cmd)
+{
+       DECLARE_COMPLETION(wait);
+       struct ata_queued_cmd *qc;
+       unsigned long flags;
+       int rc;
+
+       qc = ata_qc_new_init(ap, dev);
+       BUG_ON(qc == NULL);
+
+       qc->tf.command = cmd;
+       qc->tf.flags |= ATA_TFLAG_DEVICE;
+       qc->tf.protocol = ATA_PROT_NODATA;
+
+       qc->waiting = &wait;
+       qc->complete_fn = ata_qc_complete_noop;
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       rc = ata_qc_issue(qc);
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       if (!rc)
+               wait_for_completion(&wait);
+
+       return rc;
+}
+
+static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
+{
+       u8 cmd;
+
+       if (!ata_try_flush_cache(dev))
+               return 0;
+
+       if (ata_id_has_flush_ext(dev->id))
+               cmd = ATA_CMD_FLUSH_EXT;
+       else
+               cmd = ATA_CMD_FLUSH;
+
+       return ata_do_simple_cmd(ap, dev, cmd);
+}
+
+static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev)
+{
+       return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1);
+}
+
+static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
+{
+       return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE);
+}
+
+/**
+ *     ata_device_resume - wakeup a previously suspended devices
+ *
+ *     Kick the drive back into action, by sending it an idle immediate
+ *     command and making sure its transfer mode matches between drive
+ *     and host.
+ *
+ */
+int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
+{
+       if (ap->flags & ATA_FLAG_SUSPENDED) {
+               ap->flags &= ~ATA_FLAG_SUSPENDED;
+               ata_set_mode(ap);
+       }
+       if (!ata_dev_present(dev))
+               return 0;
+       if (dev->class == ATA_DEV_ATA)
+               ata_start_drive(ap, dev);
+
+       return 0;
+}
+
+/**
+ *     ata_device_suspend - prepare a device for suspend
+ *
+ *     Flush the cache on the drive, if appropriate, then issue a
+ *     standbynow command.
+ *
+ */
+int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
+{
+       if (!ata_dev_present(dev))
+               return 0;
+       if (dev->class == ATA_DEV_ATA)
+               ata_flush_cache(ap, dev);
+
+       ata_standby_drive(ap, dev);
+       ap->flags |= ATA_FLAG_SUSPENDED;
+       return 0;
+}
+
 /**
  *     ata_port_start - Set port up for dma.
  *     @ap: Port to initialize
@@ -4860,6 +4958,23 @@

        return (tmp == bits->val) ? 1 : 0;
 }
+
+int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+       return 0;
+}
+
+int ata_pci_device_resume(struct pci_dev *pdev)
+{
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       pci_enable_device(pdev);
+       pci_set_master(pdev);
+       return 0;
+}
 #endif /* CONFIG_PCI */


@@ -4963,4 +5078,11 @@
 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
+EXPORT_SYMBOL_GPL(ata_pci_device_resume);
 #endif /* CONFIG_PCI */
+
+EXPORT_SYMBOL_GPL(ata_device_suspend);
+EXPORT_SYMBOL_GPL(ata_device_resume);
+EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
+EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
diff -Naur linux-source-2.6.15/drivers/scsi/libata-scsi.c linux-source-2.6.15-ata/drivers/scsi/libata-scsi.c
--- linux-source-2.6.15/drivers/scsi/libata-scsi.c      2006-01-03 04:21:10.000000000 +0100
+++ linux-source-2.6.15-ata/drivers/scsi/libata-scsi.c  2006-03-02 08:03:14.000000000 +0100
@@ -802,6 +802,22 @@
        return 1;
 }

+int ata_scsi_device_resume(struct scsi_device *sdev)
+{
+       struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+       struct ata_device *dev = &ap->device[sdev->id];
+
+       return ata_device_resume(ap, dev);
+}
+
+int ata_scsi_device_suspend(struct scsi_device *sdev)
+{
+       struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+       struct ata_device *dev = &ap->device[sdev->id];
+
+       return ata_device_suspend(ap, dev);
+}
+

 /**
  *     ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
diff -Naur linux-source-2.6.15/drivers/scsi/scsi_lib.c linux-source-2.6.15-ata/drivers/scsi/scsi_lib.c
--- linux-source-2.6.15/drivers/scsi/scsi_lib.c 2006-02-21 18:40:50.000000000 +0100
+++ linux-source-2.6.15-ata/drivers/scsi/scsi_lib.c     2006-03-02 07:53:01.000000000 +0100
@@ -1904,8 +1904,9 @@
 void
 scsi_device_resume(struct scsi_device *sdev)
 {
-       if(scsi_device_set_state(sdev, SDEV_RUNNING))
+       if (scsi_device_set_state(sdev, SDEV_RUNNING))
                return;
+
        scsi_run_queue(sdev->request_queue);
 }
 EXPORT_SYMBOL(scsi_device_resume);
diff -Naur linux-source-2.6.15/drivers/scsi/scsi_sysfs.c linux-source-2.6.15-ata/drivers/scsi/scsi_sysfs.c
--- linux-source-2.6.15/drivers/scsi/scsi_sysfs.c       2006-01-03 04:21:10.000000000 +0100
+++ linux-source-2.6.15-ata/drivers/scsi/scsi_sysfs.c   2006-03-02 07:53:01.000000000 +0100
@@ -263,9 +263,40 @@
        return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
 }

+static int scsi_bus_suspend(struct device * dev, pm_message_t state)
+{
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct scsi_host_template *sht = sdev->host->hostt;
+       int err;
+
+       err = scsi_device_quiesce(sdev);
+       if (err)
+               return err;
+
+       if (sht->suspend)
+               err = sht->suspend(sdev);
+
+       return err;
+}
+
+static int scsi_bus_resume(struct device * dev)
+{
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct scsi_host_template *sht = sdev->host->hostt;
+       int err = 0;
+
+       if (sht->resume)
+               err = sht->resume(sdev);
+
+       scsi_device_resume(sdev);
+       return err;
+}
+
 struct bus_type scsi_bus_type = {
         .name          = "scsi",
         .match         = scsi_bus_match,
+       .suspend        = scsi_bus_suspend,
+       .resume         = scsi_bus_resume,
 };

 int scsi_sysfs_register(void)
diff -Naur linux-source-2.6.15/include/linux/ata.h linux-source-2.6.15-ata/include/linux/ata.h
--- linux-source-2.6.15/include/linux/ata.h     2006-01-03 04:21:10.000000000 +0100
+++ linux-source-2.6.15-ata/include/linux/ata.h 2006-03-02 08:13:14.000000000 +0100
@@ -142,6 +142,8 @@
        ATA_CMD_VERIFY          = 0x40,
        ATA_CMD_VERIFY_EXT      = 0x42,
        ATA_CMD_INIT_DEV_PARAMS = 0x91,
+       ATA_CMD_STANDBYNOW1     = 0xE0,
+       ATA_CMD_IDLEIMMEDIATE   = 0xE1,

        /* SETFEATURES stuff */
        SETFEATURES_XFER        = 0x03,
diff -Naur linux-source-2.6.15/include/linux/libata.h linux-source-2.6.15-ata/include/linux/libata.h
--- linux-source-2.6.15/include/linux/libata.h  2006-01-03 04:21:10.000000000 +0100
+++ linux-source-2.6.15-ata/include/linux/libata.h      2006-03-02 08:26:05.000000000 +0100
@@ -123,6 +123,7 @@
                                             * proper HSM is in place. */
        ATA_FLAG_DEBUGMSG       = (1 << 10),
        ATA_FLAG_NO_ATAPI       = (1 << 11), /* No ATAPI support */
+       ATA_FLAG_SUSPENDED      = (1 << 12), /* port is suspended */

        ATA_QCFLAG_ACTIVE       = (1 << 1), /* cmd not yet ack'd to scsi lyer */
        ATA_QCFLAG_SG           = (1 << 3), /* have s/g table? */
@@ -436,6 +437,8 @@
 extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                             unsigned int n_ports);
 extern void ata_pci_remove_one (struct pci_dev *pdev);
+extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state);
+extern int ata_pci_device_resume(struct pci_dev *pdev);
 #endif /* CONFIG_PCI */
 extern int ata_device_add(const struct ata_probe_ent *ent);
 extern void ata_host_set_remove(struct ata_host_set *host_set);
@@ -446,6 +449,10 @@
 extern int ata_scsi_release(struct Scsi_Host *host);
 extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
 extern int ata_ratelimit(void);
+extern int ata_scsi_device_resume(struct scsi_device *);
+extern int ata_scsi_device_suspend(struct scsi_device *);
+extern int ata_device_resume(struct ata_port *, struct ata_device *);
+extern int ata_device_suspend(struct ata_port *, struct ata_device *);

 /*
  * Default driver ops implementations
diff -Naur linux-source-2.6.15/include/scsi/scsi_host.h linux-source-2.6.15-ata/include/scsi/scsi_host.h
--- linux-source-2.6.15/include/scsi/scsi_host.h        2006-01-03 04:21:10.000000000 +0100
+++ linux-source-2.6.15-ata/include/scsi/scsi_host.h    2006-03-02 07:53:01.000000000 +0100
@@ -296,6 +296,12 @@
        int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);

        /*
+        * suspend support
+        */
+       int (*resume)(struct scsi_device *);
+       int (*suspend)(struct scsi_device *);
+
+       /*
         * Name of proc directory
         */
        char *proc_name;
  • Save the file under e.g. /usr/src/libata_suspend-2.6.15-7.patch
  • apt-get install linux-source-2.6.15
  • cd /usr/src
  • tar xjf linux-source-2.6.15.tar.bz2
  • cd linux-source-2.6.15
  • patch -p1 < ../libata_suspend-2.6.15-7.patch
  • cp /boot/config-2.6.15-1-686 .config
    I assume you have already installed the Debian 2.6.15-1-686 kernel so we can simply apply the original config to our kernel
  • make-kpkg clean
  • make-kpkg --initrd --us --uc --revision 2.6.15-7 --append-to-version -1-686-str kernel_image
  • cd ..
  • dpkg -i linux-image-2.6.15-1-686-str_2.6.15-7_i386.deb
  • Now ou have a second kernel named 2.6.15-1-686-str and capable of suspend-to-ram :-)

Hardware todo

  • screen
    • didn't try fb, probably don't work with suspend-to-ram
    • 3D accel??
    • extern CRT: cf i810switch + need other resolutions??
    • Intel drivers ?
  • suspend-to-ram
    • merge acpi_handlers....
  • pcmcia/cardbus, not yet tested
  • smartcard reader
    • cf TexasInstrumentsSmartCardController
  • wireless
  • irda
  • bluetooth
  • modem
  • serial/parallel
  • tv out
  • SMBus
    • this is for the sensors
    • apt-get install lm-sensors
    • modules: i2c-i801 (by udev), i2c-dev
    • sensors-detect -> module eeprom