Author: waldi
Date: Tue Oct 10 14:43:21 2006
New Revision: 7593

Added:
   
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-1.patch
   
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-2.patch
   
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-3.patch
   
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-4.patch
   
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-1.patch
   
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-2.patch
   
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-3.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/3

Log:
Add AHCI suspend support.

* debian/changelog: Update.
* debian/patches/features/all/drivers/scsi-ahci-*: Add.
* debian/patches/series/3: Add patches.


Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog      (original)
+++ dists/trunk/linux-2.6/debian/changelog      Tue Oct 10 14:43:21 2006
@@ -4,6 +4,7 @@
   * Fix home of patch apply script.
   * Unify CPUSET option. (closes: #391931)
   * Support xen version 3.0.3-1 and 3.0.3-rc1.
+  * Add AHCI suspend support. 
 
   [ Steve Langasek ]
   * [alpha] restore alpha-prctl.patch, which keeps disappearing every time
@@ -30,7 +31,7 @@
   * bugfix/sky2-receive-FIFO-fix.patch: fix sky2 hangs on some chips
     Thanks to Stephen Hemminger for the patch. (Closes: #391382)
 
- -- Frederik Schüler <[EMAIL PROTECTED]>  Tue, 10 Oct 2006 13:50:08 +0200
+ -- Bastian Blank <[EMAIL PROTECTED]>  Tue, 10 Oct 2006 16:40:26 +0200
 
 linux-2.6 (2.6.18-2) unstable; urgency=low
 

Added: 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-1.patch
==============================================================================
--- (empty file)
+++ 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-1.patch
 Tue Oct 10 14:43:21 2006
@@ -0,0 +1,183 @@
+# [PATCH] The redefinition of ahci_start_engine() and ahci_stop_engine()
+# 5457f2194ad198a0aba4190ec99a6a81846fdca5
+
+diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+index 77e7202..f1516ca 100644
+--- a/drivers/scsi/ahci.c
++++ b/drivers/scsi/ahci.c
+@@ -205,6 +205,8 @@ static irqreturn_t ahci_interrupt (int i
+ static void ahci_irq_clear(struct ata_port *ap);
+ static int ahci_port_start(struct ata_port *ap);
+ static void ahci_port_stop(struct ata_port *ap);
++static int ahci_start_engine(void __iomem *port_mmio);
++static int ahci_stop_engine(void __iomem *port_mmio);
+ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+ static void ahci_qc_prep(struct ata_queued_cmd *qc);
+ static u8 ahci_check_status(struct ata_port *ap);
+@@ -508,41 +510,64 @@ static void ahci_scr_write (struct ata_p
+       writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+-static int ahci_stop_engine(struct ata_port *ap)
++static int ahci_stop_engine(void __iomem *port_mmio)
+ {
+-      void __iomem *mmio = ap->host_set->mmio_base;
+-      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+-      int work;
+       u32 tmp;
+ 
+       tmp = readl(port_mmio + PORT_CMD);
++
++      /* Check if the HBA is idle */
++      if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0)
++              return 0;
++
++      /* Setting HBA to idle */
+       tmp &= ~PORT_CMD_START;
+       writel(tmp, port_mmio + PORT_CMD);
+ 
+-      /* wait for engine to stop.  TODO: this could be
++      /* wait for engine to stop. This could be
+        * as long as 500 msec
+        */
+-      work = 1000;
+-      while (work-- > 0) {
+-              tmp = readl(port_mmio + PORT_CMD);
+-              if ((tmp & PORT_CMD_LIST_ON) == 0)
+-                      return 0;
+-              udelay(10);
+-      }
++      tmp = ata_wait_register(port_mmio + PORT_CMD,
++                              PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
++      if(tmp & PORT_CMD_LIST_ON)
++              return -EIO;
+ 
+-      return -EIO;
++      return 0;
+ }
+ 
+-static void ahci_start_engine(struct ata_port *ap)
++static int ahci_start_engine(void __iomem *port_mmio)
+ {
+-      void __iomem *mmio = ap->host_set->mmio_base;
+-      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       u32 tmp;
+ 
++      /*
++       * Get current status
++       */
+       tmp = readl(port_mmio + PORT_CMD);
++
++      /*
++       * AHCI rev 1.1 section 10.3.1:
++       * Software shall not set PxCMD.ST to '1' until it verifies
++       * that PxCMD.CR is '0' and has set PxCMD.FRE to '1'
++       */
++      if ((tmp & PORT_CMD_FIS_RX) == 0)
++              return -EPERM;
++
++      /*
++       * wait for engine to become idle.
++       */
++      tmp = ata_wait_register(port_mmio + PORT_CMD,
++                              PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1,500);
++      if(tmp & PORT_CMD_LIST_ON)
++              return -EBUSY;
++
++      /*
++       * Start DMA
++       */
+       tmp |= PORT_CMD_START;
+       writel(tmp, port_mmio + PORT_CMD);
+       readl(port_mmio + PORT_CMD); /* flush */
++
++      return 0;
+ }
+ 
+ static unsigned int ahci_dev_classify(struct ata_port *ap)
+@@ -626,7 +651,7 @@ static int ahci_softreset(struct ata_por
+       }
+ 
+       /* prepare for SRST (AHCI-1.1 10.4.1) */
+-      rc = ahci_stop_engine(ap);
++      rc = ahci_stop_engine(port_mmio);
+       if (rc) {
+               reason = "failed to stop engine";
+               goto fail_restart;
+@@ -647,7 +672,7 @@ static int ahci_softreset(struct ata_por
+       }
+ 
+       /* restart engine */
+-      ahci_start_engine(ap);
++      ahci_start_engine(port_mmio);
+ 
+       ata_tf_init(ap->device, &tf);
+       fis = pp->cmd_tbl;
+@@ -706,7 +731,7 @@ static int ahci_softreset(struct ata_por
+       return 0;
+ 
+  fail_restart:
+-      ahci_start_engine(ap);
++      ahci_start_engine(port_mmio);
+  fail:
+       ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
+       return rc;
+@@ -717,11 +742,13 @@ static int ahci_hardreset(struct ata_por
+       struct ahci_port_priv *pp = ap->private_data;
+       u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+       struct ata_taskfile tf;
++      void __iomem *mmio = ap->host_set->mmio_base;
++      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       int rc;
+ 
+       DPRINTK("ENTER\n");
+ 
+-      ahci_stop_engine(ap);
++      ahci_stop_engine(port_mmio);
+ 
+       /* clear D2H reception area to properly wait for D2H FIS */
+       ata_tf_init(ap->device, &tf);
+@@ -730,7 +757,7 @@ static int ahci_hardreset(struct ata_por
+ 
+       rc = sata_std_hardreset(ap, class);
+ 
+-      ahci_start_engine(ap);
++      ahci_start_engine(port_mmio);
+ 
+       if (rc == 0 && ata_port_online(ap))
+               *class = ahci_dev_classify(ap);
+@@ -1052,10 +1079,13 @@ static void ahci_thaw(struct ata_port *a
+ 
+ static void ahci_error_handler(struct ata_port *ap)
+ {
++      void __iomem *mmio = ap->host_set->mmio_base;
++      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
++
+       if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
+               /* restart engine */
+-              ahci_stop_engine(ap);
+-              ahci_start_engine(ap);
++              ahci_stop_engine(port_mmio);
++              ahci_start_engine(port_mmio);
+       }
+ 
+       /* perform recovery */
+@@ -1066,14 +1096,16 @@ static void ahci_error_handler(struct at
+ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
+ {
+       struct ata_port *ap = qc->ap;
++      void __iomem *mmio = ap->host_set->mmio_base;
++      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ 
+       if (qc->flags & ATA_QCFLAG_FAILED)
+               qc->err_mask |= AC_ERR_OTHER;
+ 
+       if (qc->err_mask) {
+               /* make DMA engine forget about the failed command */
+-              ahci_stop_engine(ap);
+-              ahci_start_engine(ap);
++              ahci_stop_engine(port_mmio);
++              ahci_start_engine(port_mmio);
+       }
+ }
+ 

Added: 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-2.patch
==============================================================================
--- (empty file)
+++ 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-2.patch
 Tue Oct 10 14:43:21 2006
@@ -0,0 +1,297 @@
+# [PATCH] ahci: relocate several internal functions
+# 254950cd56fee220c9d548f3e57211b95976ba64
+
+diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+index f1516ca..92e2b95 100644
+--- a/drivers/scsi/ahci.c
++++ b/drivers/scsi/ahci.c
+@@ -205,8 +205,6 @@ static irqreturn_t ahci_interrupt (int i
+ static void ahci_irq_clear(struct ata_port *ap);
+ static int ahci_port_start(struct ata_port *ap);
+ static void ahci_port_stop(struct ata_port *ap);
+-static int ahci_start_engine(void __iomem *port_mmio);
+-static int ahci_stop_engine(void __iomem *port_mmio);
+ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+ static void ahci_qc_prep(struct ata_queued_cmd *qc);
+ static u8 ahci_check_status(struct ata_port *ap);
+@@ -374,108 +372,6 @@ static inline void __iomem *ahci_port_ba
+       return (void __iomem *) ahci_port_base_ul((unsigned long)base, port);
+ }
+ 
+-static int ahci_port_start(struct ata_port *ap)
+-{
+-      struct device *dev = ap->host_set->dev;
+-      struct ahci_host_priv *hpriv = ap->host_set->private_data;
+-      struct ahci_port_priv *pp;
+-      void __iomem *mmio = ap->host_set->mmio_base;
+-      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+-      void *mem;
+-      dma_addr_t mem_dma;
+-      int rc;
+-
+-      pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+-      if (!pp)
+-              return -ENOMEM;
+-      memset(pp, 0, sizeof(*pp));
+-
+-      rc = ata_pad_alloc(ap, dev);
+-      if (rc) {
+-              kfree(pp);
+-              return rc;
+-      }
+-
+-      mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, 
GFP_KERNEL);
+-      if (!mem) {
+-              ata_pad_free(ap, dev);
+-              kfree(pp);
+-              return -ENOMEM;
+-      }
+-      memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
+-
+-      /*
+-       * First item in chunk of DMA memory: 32-slot command table,
+-       * 32 bytes each in size
+-       */
+-      pp->cmd_slot = mem;
+-      pp->cmd_slot_dma = mem_dma;
+-
+-      mem += AHCI_CMD_SLOT_SZ;
+-      mem_dma += AHCI_CMD_SLOT_SZ;
+-
+-      /*
+-       * Second item: Received-FIS area
+-       */
+-      pp->rx_fis = mem;
+-      pp->rx_fis_dma = mem_dma;
+-
+-      mem += AHCI_RX_FIS_SZ;
+-      mem_dma += AHCI_RX_FIS_SZ;
+-
+-      /*
+-       * Third item: data area for storing a single command
+-       * and its scatter-gather table
+-       */
+-      pp->cmd_tbl = mem;
+-      pp->cmd_tbl_dma = mem_dma;
+-
+-      ap->private_data = pp;
+-
+-      if (hpriv->cap & HOST_CAP_64)
+-              writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + 
PORT_LST_ADDR_HI);
+-      writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
+-      readl(port_mmio + PORT_LST_ADDR); /* flush */
+-
+-      if (hpriv->cap & HOST_CAP_64)
+-              writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + 
PORT_FIS_ADDR_HI);
+-      writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
+-      readl(port_mmio + PORT_FIS_ADDR); /* flush */
+-
+-      writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
+-             PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
+-             PORT_CMD_START, port_mmio + PORT_CMD);
+-      readl(port_mmio + PORT_CMD); /* flush */
+-
+-      return 0;
+-}
+-
+-
+-static void ahci_port_stop(struct ata_port *ap)
+-{
+-      struct device *dev = ap->host_set->dev;
+-      struct ahci_port_priv *pp = ap->private_data;
+-      void __iomem *mmio = ap->host_set->mmio_base;
+-      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+-      u32 tmp;
+-
+-      tmp = readl(port_mmio + PORT_CMD);
+-      tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX);
+-      writel(tmp, port_mmio + PORT_CMD);
+-      readl(port_mmio + PORT_CMD); /* flush */
+-
+-      /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so
+-       * this is slightly incorrect.
+-       */
+-      msleep(500);
+-
+-      ap->private_data = NULL;
+-      dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
+-                        pp->cmd_slot, pp->cmd_slot_dma);
+-      ata_pad_free(ap, dev);
+-      kfree(pp);
+-}
+-
+ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
+ {
+       unsigned int sc_reg;
+@@ -510,31 +406,6 @@ static void ahci_scr_write (struct ata_p
+       writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+-static int ahci_stop_engine(void __iomem *port_mmio)
+-{
+-      u32 tmp;
+-
+-      tmp = readl(port_mmio + PORT_CMD);
+-
+-      /* Check if the HBA is idle */
+-      if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0)
+-              return 0;
+-
+-      /* Setting HBA to idle */
+-      tmp &= ~PORT_CMD_START;
+-      writel(tmp, port_mmio + PORT_CMD);
+-
+-      /* wait for engine to stop. This could be
+-       * as long as 500 msec
+-       */
+-      tmp = ata_wait_register(port_mmio + PORT_CMD,
+-                              PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
+-      if(tmp & PORT_CMD_LIST_ON)
+-              return -EIO;
+-
+-      return 0;
+-}
+-
+ static int ahci_start_engine(void __iomem *port_mmio)
+ {
+       u32 tmp;
+@@ -570,6 +441,31 @@ static int ahci_start_engine(void __iome
+       return 0;
+ }
+ 
++static int ahci_stop_engine(void __iomem *port_mmio)
++{
++      u32 tmp;
++
++      tmp = readl(port_mmio + PORT_CMD);
++
++      /* Check if the HBA is idle */
++      if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0)
++              return 0;
++
++      /* Setting HBA to idle */
++      tmp &= ~PORT_CMD_START;
++      writel(tmp, port_mmio + PORT_CMD);
++
++      /* wait for engine to stop. This could be
++       * as long as 500 msec
++       */
++      tmp = ata_wait_register(port_mmio + PORT_CMD,
++                              PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
++      if(tmp & PORT_CMD_LIST_ON)
++              return -EIO;
++
++      return 0;
++}
++
+ static unsigned int ahci_dev_classify(struct ata_port *ap)
+ {
+       void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+@@ -1109,6 +1005,107 @@ static void ahci_post_internal_cmd(struc
+       }
+ }
+ 
++static int ahci_port_start(struct ata_port *ap)
++{
++      struct device *dev = ap->host_set->dev;
++      struct ahci_host_priv *hpriv = ap->host_set->private_data;
++      struct ahci_port_priv *pp;
++      void __iomem *mmio = ap->host_set->mmio_base;
++      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
++      void *mem;
++      dma_addr_t mem_dma;
++      int rc;
++
++      pp = kmalloc(sizeof(*pp), GFP_KERNEL);
++      if (!pp)
++              return -ENOMEM;
++      memset(pp, 0, sizeof(*pp));
++
++      rc = ata_pad_alloc(ap, dev);
++      if (rc) {
++              kfree(pp);
++              return rc;
++      }
++
++      mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, 
GFP_KERNEL);
++      if (!mem) {
++              ata_pad_free(ap, dev);
++              kfree(pp);
++              return -ENOMEM;
++      }
++      memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
++
++      /*
++       * First item in chunk of DMA memory: 32-slot command table,
++       * 32 bytes each in size
++       */
++      pp->cmd_slot = mem;
++      pp->cmd_slot_dma = mem_dma;
++
++      mem += AHCI_CMD_SLOT_SZ;
++      mem_dma += AHCI_CMD_SLOT_SZ;
++
++      /*
++       * Second item: Received-FIS area
++       */
++      pp->rx_fis = mem;
++      pp->rx_fis_dma = mem_dma;
++
++      mem += AHCI_RX_FIS_SZ;
++      mem_dma += AHCI_RX_FIS_SZ;
++
++      /*
++       * Third item: data area for storing a single command
++       * and its scatter-gather table
++       */
++      pp->cmd_tbl = mem;
++      pp->cmd_tbl_dma = mem_dma;
++
++      ap->private_data = pp;
++
++      if (hpriv->cap & HOST_CAP_64)
++              writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + 
PORT_LST_ADDR_HI);
++      writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
++      readl(port_mmio + PORT_LST_ADDR); /* flush */
++
++      if (hpriv->cap & HOST_CAP_64)
++              writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + 
PORT_FIS_ADDR_HI);
++      writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
++      readl(port_mmio + PORT_FIS_ADDR); /* flush */
++
++      writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
++             PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
++             PORT_CMD_START, port_mmio + PORT_CMD);
++      readl(port_mmio + PORT_CMD); /* flush */
++
++      return 0;
++}
++
++static void ahci_port_stop(struct ata_port *ap)
++{
++      struct device *dev = ap->host_set->dev;
++      struct ahci_port_priv *pp = ap->private_data;
++      void __iomem *mmio = ap->host_set->mmio_base;
++      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
++      u32 tmp;
++
++      tmp = readl(port_mmio + PORT_CMD);
++      tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX);
++      writel(tmp, port_mmio + PORT_CMD);
++      readl(port_mmio + PORT_CMD); /* flush */
++
++      /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so
++       * this is slightly incorrect.
++       */
++      msleep(500);
++
++      ap->private_data = NULL;
++      dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
++                        pp->cmd_slot, pp->cmd_slot_dma);
++      ata_pad_free(ap, dev);
++      kfree(pp);
++}
++
+ static void ahci_setup_port(struct ata_ioports *port, unsigned long base,
+                           unsigned int port_idx)
+ {

Added: 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-3.patch
==============================================================================
--- (empty file)
+++ 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-3.patch
 Tue Oct 10 14:43:21 2006
@@ -0,0 +1,68 @@
+# [PATCH] ahci: cosmetic changes to ahci_start/stop_engine()
+# d8fcd116d203dfe2f6c272d0cd67724b172f1bc2
+
+diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+index 92e2b95..ee00aed 100644
+--- a/drivers/scsi/ahci.c
++++ b/drivers/scsi/ahci.c
+@@ -410,30 +410,23 @@ static int ahci_start_engine(void __iome
+ {
+       u32 tmp;
+ 
+-      /*
+-       * Get current status
+-       */
++      /* get current status */
+       tmp = readl(port_mmio + PORT_CMD);
+ 
+-      /*
+-       * AHCI rev 1.1 section 10.3.1:
++      /* AHCI rev 1.1 section 10.3.1:
+        * Software shall not set PxCMD.ST to '1' until it verifies
+        * that PxCMD.CR is '0' and has set PxCMD.FRE to '1'
+        */
+       if ((tmp & PORT_CMD_FIS_RX) == 0)
+               return -EPERM;
+ 
+-      /*
+-       * wait for engine to become idle.
+-       */
++      /* wait for engine to become idle */
+       tmp = ata_wait_register(port_mmio + PORT_CMD,
+                               PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1,500);
+-      if(tmp & PORT_CMD_LIST_ON)
++      if (tmp & PORT_CMD_LIST_ON)
+               return -EBUSY;
+ 
+-      /*
+-       * Start DMA
+-       */
++      /* start DMA */
+       tmp |= PORT_CMD_START;
+       writel(tmp, port_mmio + PORT_CMD);
+       readl(port_mmio + PORT_CMD); /* flush */
+@@ -447,20 +440,18 @@ static int ahci_stop_engine(void __iomem
+ 
+       tmp = readl(port_mmio + PORT_CMD);
+ 
+-      /* Check if the HBA is idle */
++      /* check if the HBA is idle */
+       if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0)
+               return 0;
+ 
+-      /* Setting HBA to idle */
++      /* setting HBA to idle */
+       tmp &= ~PORT_CMD_START;
+       writel(tmp, port_mmio + PORT_CMD);
+ 
+-      /* wait for engine to stop. This could be
+-       * as long as 500 msec
+-       */
++      /* wait for engine to stop. This could be as long as 500 msec */
+       tmp = ata_wait_register(port_mmio + PORT_CMD,
+                               PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
+-      if(tmp & PORT_CMD_LIST_ON)
++      if (tmp & PORT_CMD_LIST_ON)
+               return -EIO;
+ 
+       return 0;

Added: 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-4.patch
==============================================================================
--- (empty file)
+++ 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-cleanup-4.patch
 Tue Oct 10 14:43:21 2006
@@ -0,0 +1,42 @@
+# [PATCH] ahci: simplify ahci_start_engine()
+# 9f5920567bfabbd1be26112a31c44652b6587394
+
+diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+index ee00aed..e02b9c6 100644
+--- a/drivers/scsi/ahci.c
++++ b/drivers/scsi/ahci.c
+@@ -406,32 +406,15 @@ static void ahci_scr_write (struct ata_p
+       writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+-static int ahci_start_engine(void __iomem *port_mmio)
++static void ahci_start_engine(void __iomem *port_mmio)
+ {
+       u32 tmp;
+ 
+-      /* get current status */
+-      tmp = readl(port_mmio + PORT_CMD);
+-
+-      /* AHCI rev 1.1 section 10.3.1:
+-       * Software shall not set PxCMD.ST to '1' until it verifies
+-       * that PxCMD.CR is '0' and has set PxCMD.FRE to '1'
+-       */
+-      if ((tmp & PORT_CMD_FIS_RX) == 0)
+-              return -EPERM;
+-
+-      /* wait for engine to become idle */
+-      tmp = ata_wait_register(port_mmio + PORT_CMD,
+-                              PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1,500);
+-      if (tmp & PORT_CMD_LIST_ON)
+-              return -EBUSY;
+-
+       /* start DMA */
++      tmp = readl(port_mmio + PORT_CMD);
+       tmp |= PORT_CMD_START;
+       writel(tmp, port_mmio + PORT_CMD);
+       readl(port_mmio + PORT_CMD); /* flush */
+-
+-      return 0;
+ }
+ 
+ static int ahci_stop_engine(void __iomem *port_mmio)

Added: 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-1.patch
==============================================================================
--- (empty file)
+++ 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-1.patch
 Tue Oct 10 14:43:21 2006
@@ -0,0 +1,281 @@
+# [PATCH] libata: improve driver initialization and deinitialization
+# 0be0aa98985dfec42502c0d0af2a1baff9bdb19f
+
+diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+index e02b9c6..fb71fa7 100644
+--- a/drivers/scsi/ahci.c
++++ b/drivers/scsi/ahci.c
+@@ -92,7 +92,9 @@ enum {
+       HOST_AHCI_EN            = (1 << 31), /* AHCI enabled */
+ 
+       /* HOST_CAP bits */
++      HOST_CAP_SSC            = (1 << 14), /* Slumber capable */
+       HOST_CAP_CLO            = (1 << 24), /* Command List Override support */
++      HOST_CAP_SSS            = (1 << 27), /* Staggered Spin-up */
+       HOST_CAP_NCQ            = (1 << 30), /* Native Command Queueing */
+       HOST_CAP_64             = (1 << 31), /* PCI DAC (64-bit DMA) support */
+ 
+@@ -155,6 +157,7 @@ enum {
+       PORT_CMD_SPIN_UP        = (1 << 1), /* Spin up device */
+       PORT_CMD_START          = (1 << 0), /* Enable port DMA engine */
+ 
++      PORT_CMD_ICC_MASK       = (0xf << 28), /* i/f ICC state mask */
+       PORT_CMD_ICC_ACTIVE     = (0x1 << 28), /* Put i/f in active state */
+       PORT_CMD_ICC_PARTIAL    = (0x2 << 28), /* Put i/f in partial state */
+       PORT_CMD_ICC_SLUMBER    = (0x6 << 28), /* Put i/f in slumber state */
+@@ -440,6 +443,135 @@ static int ahci_stop_engine(void __iomem
+       return 0;
+ }
+ 
++static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap,
++                            dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
++{
++      u32 tmp;
++
++      /* set FIS registers */
++      if (cap & HOST_CAP_64)
++              writel((cmd_slot_dma >> 16) >> 16, port_mmio + 
PORT_LST_ADDR_HI);
++      writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
++
++      if (cap & HOST_CAP_64)
++              writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI);
++      writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
++
++      /* enable FIS reception */
++      tmp = readl(port_mmio + PORT_CMD);
++      tmp |= PORT_CMD_FIS_RX;
++      writel(tmp, port_mmio + PORT_CMD);
++
++      /* flush */
++      readl(port_mmio + PORT_CMD);
++}
++
++static int ahci_stop_fis_rx(void __iomem *port_mmio)
++{
++      u32 tmp;
++
++      /* disable FIS reception */
++      tmp = readl(port_mmio + PORT_CMD);
++      tmp &= ~PORT_CMD_FIS_RX;
++      writel(tmp, port_mmio + PORT_CMD);
++
++      /* wait for completion, spec says 500ms, give it 1000 */
++      tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_FIS_ON,
++                              PORT_CMD_FIS_ON, 10, 1000);
++      if (tmp & PORT_CMD_FIS_ON)
++              return -EBUSY;
++
++      return 0;
++}
++
++static void ahci_power_up(void __iomem *port_mmio, u32 cap)
++{
++      u32 cmd;
++
++      cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
++
++      /* spin up device */
++      if (cap & HOST_CAP_SSS) {
++              cmd |= PORT_CMD_SPIN_UP;
++              writel(cmd, port_mmio + PORT_CMD);
++      }
++
++      /* wake up link */
++      writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD);
++}
++
++static void ahci_power_down(void __iomem *port_mmio, u32 cap)
++{
++      u32 cmd, scontrol;
++
++      cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
++
++      if (cap & HOST_CAP_SSC) {
++              /* enable transitions to slumber mode */
++              scontrol = readl(port_mmio + PORT_SCR_CTL);
++              if ((scontrol & 0x0f00) > 0x100) {
++                      scontrol &= ~0xf00;
++                      writel(scontrol, port_mmio + PORT_SCR_CTL);
++              }
++
++              /* put device into slumber mode */
++              writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD);
++
++              /* wait for the transition to complete */
++              ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER,
++                                PORT_CMD_ICC_SLUMBER, 1, 50);
++      }
++
++      /* put device into listen mode */
++      if (cap & HOST_CAP_SSS) {
++              /* first set PxSCTL.DET to 0 */
++              scontrol = readl(port_mmio + PORT_SCR_CTL);
++              scontrol &= ~0xf;
++              writel(scontrol, port_mmio + PORT_SCR_CTL);
++
++              /* then set PxCMD.SUD to 0 */
++              cmd &= ~PORT_CMD_SPIN_UP;
++              writel(cmd, port_mmio + PORT_CMD);
++      }
++}
++
++static void ahci_init_port(void __iomem *port_mmio, u32 cap,
++                         dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
++{
++      /* power up */
++      ahci_power_up(port_mmio, cap);
++
++      /* enable FIS reception */
++      ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma);
++
++      /* enable DMA */
++      ahci_start_engine(port_mmio);
++}
++
++static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char 
**emsg)
++{
++      int rc;
++
++      /* disable DMA */
++      rc = ahci_stop_engine(port_mmio);
++      if (rc) {
++              *emsg = "failed to stop engine";
++              return rc;
++      }
++
++      /* disable FIS reception */
++      rc = ahci_stop_fis_rx(port_mmio);
++      if (rc) {
++              *emsg = "failed stop FIS RX";
++              return rc;
++      }
++
++      /* put device into slumber mode */
++      ahci_power_down(port_mmio, cap);
++
++      return 0;
++}
++
+ static unsigned int ahci_dev_classify(struct ata_port *ap)
+ {
+       void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+@@ -1037,20 +1169,8 @@ static int ahci_port_start(struct ata_po
+ 
+       ap->private_data = pp;
+ 
+-      if (hpriv->cap & HOST_CAP_64)
+-              writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + 
PORT_LST_ADDR_HI);
+-      writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
+-      readl(port_mmio + PORT_LST_ADDR); /* flush */
+-
+-      if (hpriv->cap & HOST_CAP_64)
+-              writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + 
PORT_FIS_ADDR_HI);
+-      writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
+-      readl(port_mmio + PORT_FIS_ADDR); /* flush */
+-
+-      writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
+-             PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
+-             PORT_CMD_START, port_mmio + PORT_CMD);
+-      readl(port_mmio + PORT_CMD); /* flush */
++      /* initialize port */
++      ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
+ 
+       return 0;
+ }
+@@ -1058,20 +1178,17 @@ static int ahci_port_start(struct ata_po
+ static void ahci_port_stop(struct ata_port *ap)
+ {
+       struct device *dev = ap->host_set->dev;
++      struct ahci_host_priv *hpriv = ap->host_set->private_data;
+       struct ahci_port_priv *pp = ap->private_data;
+       void __iomem *mmio = ap->host_set->mmio_base;
+       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+-      u32 tmp;
+-
+-      tmp = readl(port_mmio + PORT_CMD);
+-      tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX);
+-      writel(tmp, port_mmio + PORT_CMD);
+-      readl(port_mmio + PORT_CMD); /* flush */
++      const char *emsg = NULL;
++      int rc;
+ 
+-      /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so
+-       * this is slightly incorrect.
+-       */
+-      msleep(500);
++      /* de-initialize port */
++      rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
++      if (rc)
++              ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc);
+ 
+       ap->private_data = NULL;
+       dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
+@@ -1099,7 +1216,7 @@ static int ahci_host_init(struct ata_pro
+       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+       void __iomem *mmio = probe_ent->mmio_base;
+       u32 tmp, cap_save;
+-      unsigned int i, j, using_dac;
++      unsigned int i, using_dac;
+       int rc;
+       void __iomem *port_mmio;
+ 
+@@ -1175,6 +1292,8 @@ static int ahci_host_init(struct ata_pro
+       }
+ 
+       for (i = 0; i < probe_ent->n_ports; i++) {
++              const char *emsg = NULL;
++
+ #if 0 /* BIOSen initialize this incorrectly */
+               if (!(hpriv->port_map & (1 << i)))
+                       continue;
+@@ -1187,43 +1306,24 @@ #endif
+                               (unsigned long) mmio, i);
+ 
+               /* make sure port is not active */
+-              tmp = readl(port_mmio + PORT_CMD);
+-              VPRINTK("PORT_CMD 0x%x\n", tmp);
+-              if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+-                         PORT_CMD_FIS_RX | PORT_CMD_START)) {
+-                      tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+-                               PORT_CMD_FIS_RX | PORT_CMD_START);
+-                      writel(tmp, port_mmio + PORT_CMD);
+-                      readl(port_mmio + PORT_CMD); /* flush */
+-
+-                      /* spec says 500 msecs for each bit, so
+-                       * this is slightly incorrect.
+-                       */
+-                      msleep(500);
+-              }
+-
+-              writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
+-
+-              j = 0;
+-              while (j < 100) {
+-                      msleep(10);
+-                      tmp = readl(port_mmio + PORT_SCR_STAT);
+-                      if ((tmp & 0xf) == 0x3)
+-                              break;
+-                      j++;
+-              }
++              rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
++              if (rc)
++                      dev_printk(KERN_WARNING, &pdev->dev,
++                                 "%s (%d)\n", emsg, rc);
+ 
++              /* clear SError */
+               tmp = readl(port_mmio + PORT_SCR_ERR);
+               VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
+               writel(tmp, port_mmio + PORT_SCR_ERR);
+ 
+-              /* ack any pending irq events for this port */
++              /* clear & turn off port IRQ */
+               tmp = readl(port_mmio + PORT_IRQ_STAT);
+               VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
+               if (tmp)
+                       writel(tmp, port_mmio + PORT_IRQ_STAT);
+ 
+               writel(1 << i, mmio + HOST_IRQ_STAT);
++              writel(0, port_mmio + PORT_IRQ_MASK);
+       }
+ 
+       tmp = readl(mmio + HOST_CTL);

Added: 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-2.patch
==============================================================================
--- (empty file)
+++ 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-2.patch
 Tue Oct 10 14:43:21 2006
@@ -0,0 +1,203 @@
+# [PATCH] ahci: separate out ahci_reset_controller() and ahci_init_controller()
+# d91542c11f3981768367815cf087ad36e792ea4a
+
+diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+index fb71fa7..a9e0c5f 100644
+--- a/drivers/scsi/ahci.c
++++ b/drivers/scsi/ahci.c
+@@ -572,6 +572,94 @@ static int ahci_deinit_port(void __iomem
+       return 0;
+ }
+ 
++static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
++{
++      u32 cap_save, tmp;
++
++      cap_save = readl(mmio + HOST_CAP);
++      cap_save &= ( (1<<28) | (1<<17) );
++      cap_save |= (1 << 27);
++
++      /* global controller reset */
++      tmp = readl(mmio + HOST_CTL);
++      if ((tmp & HOST_RESET) == 0) {
++              writel(tmp | HOST_RESET, mmio + HOST_CTL);
++              readl(mmio + HOST_CTL); /* flush */
++      }
++
++      /* reset must complete within 1 second, or
++       * the hardware should be considered fried.
++       */
++      ssleep(1);
++
++      tmp = readl(mmio + HOST_CTL);
++      if (tmp & HOST_RESET) {
++              dev_printk(KERN_ERR, &pdev->dev,
++                         "controller reset failed (0x%x)\n", tmp);
++              return -EIO;
++      }
++
++      writel(HOST_AHCI_EN, mmio + HOST_CTL);
++      (void) readl(mmio + HOST_CTL);  /* flush */
++      writel(cap_save, mmio + HOST_CAP);
++      writel(0xf, mmio + HOST_PORTS_IMPL);
++      (void) readl(mmio + HOST_PORTS_IMPL);   /* flush */
++
++      if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
++              u16 tmp16;
++
++              /* configure PCS */
++              pci_read_config_word(pdev, 0x92, &tmp16);
++              tmp16 |= 0xf;
++              pci_write_config_word(pdev, 0x92, tmp16);
++      }
++
++      return 0;
++}
++
++static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
++                               int n_ports, u32 cap)
++{
++      int i, rc;
++      u32 tmp;
++
++      for (i = 0; i < n_ports; i++) {
++              void __iomem *port_mmio = ahci_port_base(mmio, i);
++              const char *emsg = NULL;
++
++#if 0 /* BIOSen initialize this incorrectly */
++              if (!(hpriv->port_map & (1 << i)))
++                      continue;
++#endif
++
++              /* make sure port is not active */
++              rc = ahci_deinit_port(port_mmio, cap, &emsg);
++              if (rc)
++                      dev_printk(KERN_WARNING, &pdev->dev,
++                                 "%s (%d)\n", emsg, rc);
++
++              /* clear SError */
++              tmp = readl(port_mmio + PORT_SCR_ERR);
++              VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
++              writel(tmp, port_mmio + PORT_SCR_ERR);
++
++              /* clear & turn off port IRQ */
++              tmp = readl(port_mmio + PORT_IRQ_STAT);
++              VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
++              if (tmp)
++                      writel(tmp, port_mmio + PORT_IRQ_STAT);
++
++              writel(1 << i, mmio + HOST_IRQ_STAT);
++              writel(0, port_mmio + PORT_IRQ_MASK);
++      }
++
++      tmp = readl(mmio + HOST_CTL);
++      VPRINTK("HOST_CTL 0x%x\n", tmp);
++      writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
++      tmp = readl(mmio + HOST_CTL);
++      VPRINTK("HOST_CTL 0x%x\n", tmp);
++}
++
+ static unsigned int ahci_dev_classify(struct ata_port *ap)
+ {
+       void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+@@ -1215,47 +1303,12 @@ static int ahci_host_init(struct ata_pro
+       struct ahci_host_priv *hpriv = probe_ent->private_data;
+       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+       void __iomem *mmio = probe_ent->mmio_base;
+-      u32 tmp, cap_save;
+       unsigned int i, using_dac;
+       int rc;
+-      void __iomem *port_mmio;
+-
+-      cap_save = readl(mmio + HOST_CAP);
+-      cap_save &= ( (1<<28) | (1<<17) );
+-      cap_save |= (1 << 27);
+-
+-      /* global controller reset */
+-      tmp = readl(mmio + HOST_CTL);
+-      if ((tmp & HOST_RESET) == 0) {
+-              writel(tmp | HOST_RESET, mmio + HOST_CTL);
+-              readl(mmio + HOST_CTL); /* flush */
+-      }
+-
+-      /* reset must complete within 1 second, or
+-       * the hardware should be considered fried.
+-       */
+-      ssleep(1);
+-
+-      tmp = readl(mmio + HOST_CTL);
+-      if (tmp & HOST_RESET) {
+-              dev_printk(KERN_ERR, &pdev->dev,
+-                         "controller reset failed (0x%x)\n", tmp);
+-              return -EIO;
+-      }
+ 
+-      writel(HOST_AHCI_EN, mmio + HOST_CTL);
+-      (void) readl(mmio + HOST_CTL);  /* flush */
+-      writel(cap_save, mmio + HOST_CAP);
+-      writel(0xf, mmio + HOST_PORTS_IMPL);
+-      (void) readl(mmio + HOST_PORTS_IMPL);   /* flush */
+-
+-      if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+-              u16 tmp16;
+-
+-              pci_read_config_word(pdev, 0x92, &tmp16);
+-              tmp16 |= 0xf;
+-              pci_write_config_word(pdev, 0x92, tmp16);
+-      }
++      rc = ahci_reset_controller(mmio, pdev);
++      if (rc)
++              return rc;
+ 
+       hpriv->cap = readl(mmio + HOST_CAP);
+       hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
+@@ -1291,46 +1344,10 @@ static int ahci_host_init(struct ata_pro
+               }
+       }
+ 
+-      for (i = 0; i < probe_ent->n_ports; i++) {
+-              const char *emsg = NULL;
+-
+-#if 0 /* BIOSen initialize this incorrectly */
+-              if (!(hpriv->port_map & (1 << i)))
+-                      continue;
+-#endif
++      for (i = 0; i < probe_ent->n_ports; i++)
++              ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);
+ 
+-              port_mmio = ahci_port_base(mmio, i);
+-              VPRINTK("mmio %p  port_mmio %p\n", mmio, port_mmio);
+-
+-              ahci_setup_port(&probe_ent->port[i],
+-                              (unsigned long) mmio, i);
+-
+-              /* make sure port is not active */
+-              rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+-              if (rc)
+-                      dev_printk(KERN_WARNING, &pdev->dev,
+-                                 "%s (%d)\n", emsg, rc);
+-
+-              /* clear SError */
+-              tmp = readl(port_mmio + PORT_SCR_ERR);
+-              VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
+-              writel(tmp, port_mmio + PORT_SCR_ERR);
+-
+-              /* clear & turn off port IRQ */
+-              tmp = readl(port_mmio + PORT_IRQ_STAT);
+-              VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
+-              if (tmp)
+-                      writel(tmp, port_mmio + PORT_IRQ_STAT);
+-
+-              writel(1 << i, mmio + HOST_IRQ_STAT);
+-              writel(0, port_mmio + PORT_IRQ_MASK);
+-      }
+-
+-      tmp = readl(mmio + HOST_CTL);
+-      VPRINTK("HOST_CTL 0x%x\n", tmp);
+-      writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
+-      tmp = readl(mmio + HOST_CTL);
+-      VPRINTK("HOST_CTL 0x%x\n", tmp);
++      ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap);
+ 
+       pci_set_master(pdev);
+ 

Added: 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-3.patch
==============================================================================
--- (empty file)
+++ 
dists/trunk/linux-2.6/debian/patches/features/all/drivers/scsi-ahci-suspend-3.patch
 Tue Oct 10 14:43:21 2006
@@ -0,0 +1,126 @@
+# [PATCH] ahci: implement Power Management support
+# c1332875cbe0c148c7f200d4f9b36b64e34d9872
+
+diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+index a9e0c5f..909a4dc 100644
+--- a/drivers/scsi/ahci.c
++++ b/drivers/scsi/ahci.c
+@@ -215,6 +215,10 @@ static void ahci_freeze(struct ata_port 
+ static void ahci_thaw(struct ata_port *ap);
+ static void ahci_error_handler(struct ata_port *ap);
+ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
++static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
++static int ahci_port_resume(struct ata_port *ap);
++static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
++static int ahci_pci_device_resume(struct pci_dev *pdev);
+ static void ahci_remove_one (struct pci_dev *pdev);
+ 
+ static struct scsi_host_template ahci_sht = {
+@@ -234,6 +238,8 @@ static struct scsi_host_template ahci_sh
+       .slave_configure        = ata_scsi_slave_config,
+       .slave_destroy          = ata_scsi_slave_destroy,
+       .bios_param             = ata_std_bios_param,
++      .suspend                = ata_scsi_device_suspend,
++      .resume                 = ata_scsi_device_resume,
+ };
+ 
+ static const struct ata_port_operations ahci_ops = {
+@@ -260,6 +266,9 @@ static const struct ata_port_operations 
+       .error_handler          = ahci_error_handler,
+       .post_internal_cmd      = ahci_post_internal_cmd,
+ 
++      .port_suspend           = ahci_port_suspend,
++      .port_resume            = ahci_port_resume,
++
+       .port_start             = ahci_port_start,
+       .port_stop              = ahci_port_stop,
+ };
+@@ -361,6 +370,8 @@ static struct pci_driver ahci_pci_driver
+       .name                   = DRV_NAME,
+       .id_table               = ahci_pci_tbl,
+       .probe                  = ahci_init_one,
++      .suspend                = ahci_pci_device_suspend,
++      .resume                 = ahci_pci_device_resume,
+       .remove                 = ahci_remove_one,
+ };
+ 
+@@ -1199,6 +1210,79 @@ static void ahci_post_internal_cmd(struc
+       }
+ }
+ 
++static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
++{
++      struct ahci_host_priv *hpriv = ap->host_set->private_data;
++      struct ahci_port_priv *pp = ap->private_data;
++      void __iomem *mmio = ap->host_set->mmio_base;
++      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
++      const char *emsg = NULL;
++      int rc;
++
++      rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
++      if (rc) {
++              ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
++              ahci_init_port(port_mmio, hpriv->cap,
++                             pp->cmd_slot_dma, pp->rx_fis_dma);
++      }
++
++      return rc;
++}
++
++static int ahci_port_resume(struct ata_port *ap)
++{
++      struct ahci_port_priv *pp = ap->private_data;
++      struct ahci_host_priv *hpriv = ap->host_set->private_data;
++      void __iomem *mmio = ap->host_set->mmio_base;
++      void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
++
++      ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
++
++      return 0;
++}
++
++static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
++{
++      struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev);
++      void __iomem *mmio = host_set->mmio_base;
++      u32 ctl;
++
++      if (mesg.event == PM_EVENT_SUSPEND) {
++              /* AHCI spec rev1.1 section 8.3.3:
++               * Software must disable interrupts prior to requesting a
++               * transition of the HBA to D3 state.
++               */
++              ctl = readl(mmio + HOST_CTL);
++              ctl &= ~HOST_IRQ_EN;
++              writel(ctl, mmio + HOST_CTL);
++              readl(mmio + HOST_CTL); /* flush */
++      }
++
++      return ata_pci_device_suspend(pdev, mesg);
++}
++
++static int ahci_pci_device_resume(struct pci_dev *pdev)
++{
++      struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev);
++      struct ahci_host_priv *hpriv = host_set->private_data;
++      void __iomem *mmio = host_set->mmio_base;
++      int rc;
++
++      ata_pci_device_do_resume(pdev);
++
++      if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
++              rc = ahci_reset_controller(mmio, pdev);
++              if (rc)
++                      return rc;
++
++              ahci_init_controller(mmio, pdev, host_set->n_ports, hpriv->cap);
++      }
++
++      ata_host_set_resume(host_set);
++
++      return 0;
++}
++
+ static int ahci_port_start(struct ata_port *ap)
+ {
+       struct device *dev = ap->host_set->dev;

Modified: dists/trunk/linux-2.6/debian/patches/series/3
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/3       (original)
+++ dists/trunk/linux-2.6/debian/patches/series/3       Tue Oct 10 14:43:21 2006
@@ -5,3 +5,10 @@
 + bugfix/mips/cobalt_hz.patch
 + bugfix/mips/real-cpu-cpuinfo.patch
 + bugfix/sky2-receive-FIFO-fix.patch
++ features/all/drivers/scsi-ahci-cleanup-1.patch
++ features/all/drivers/scsi-ahci-cleanup-2.patch
++ features/all/drivers/scsi-ahci-cleanup-3.patch
++ features/all/drivers/scsi-ahci-cleanup-4.patch
++ features/all/drivers/scsi-ahci-suspend-1.patch
++ features/all/drivers/scsi-ahci-suspend-2.patch
++ features/all/drivers/scsi-ahci-suspend-3.patch

_______________________________________________
Kernel-svn-changes mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/kernel-svn-changes

Reply via email to