This patch adds ATAPI DMA support for HT1000 (aka BCM5785) & HT1100 (aka
BCM11000) SATA Controller.

Signed-off-by: Anantha Subramanyam <[EMAIL PROTECTED]>
---
--- linux-2.6.23.11/drivers/ata/sata_svw.c.orig 2008-01-07
05:22:29.000000000 -0800
+++ linux-2.6.23.11/drivers/ata/sata_svw.c      2008-01-08
03:23:31.000000000 -0800
@@ -45,6 +45,8 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi.h>
 #include <linux/libata.h>
 
 #ifdef CONFIG_PPC_OF
@@ -53,12 +55,13 @@
 #endif /* CONFIG_PPC_OF */
 
 #define DRV_NAME       "sata_svw"
-#define DRV_VERSION    "2.3"
+#define DRV_VERSION    "2.3.1"
 
 enum {
        /* ap->flags bits */
        K2_FLAG_SATA_8_PORTS            = (1 << 24),
        K2_FLAG_NO_ATAPI_DMA            = (1 << 25),
+       K2_FLAG_BAR_POS_3                       = (1 << 26),
 
        /* Taskfile registers offsets */
        K2_SATA_TF_CMD_OFFSET           = 0x00,
@@ -88,17 +91,216 @@ enum {
        /* Port stride */
        K2_SATA_PORT_OFFSET             = 0x100,
 
-       board_svw4                      = 0,
-       board_svw8                      = 1,
+// ATAPI QDMA start
+       K2_ATAPI_FEAT_DMA_BIT   = 0x01,
+
+       /* qdma reg offsets */
+       K2_SATA_QAL_OFFSET              = 0xA0,
+       K2_SATA_QAU_OFFSET              = 0xA4,
+       K2_SATA_QPI_OFFSET              = 0xA8,
+       K2_SATA_QCI_OFFSET              = 0xAC,
+       K2_SATA_QCR_OFFSET              = 0xB0,
+       K2_SATA_QDR_OFFSET              = 0xB4,
+       K2_SATA_QSR_OFFSET              = 0xB8,
+       K2_SATA_QMR_OFFSET              = 0xBC,
+
+       K2_SATA_GLB_CTL_OFFSET  = 0x1000,
+       K2_SATA_GLB_STS_OFFSET  = 0x1004,
+
+       K2_SATA_ENABLE_INTRS            = 0x21,         // 0x3F, want
only done & common error
+       K2_SATA_CLEAR_ALL_INTRS         = 0xFFFFFFFF,
+       
+       K2_SATA_NUM_DESCRIPTORS         = 4,            // min 2 for
ATAPI, but min 4 for our hw
+       K2_SATA_QDMA_MODE_ON            = 1,
+    K2_SATA_QDMA_ENABLE        = 0x01,
+
+    K2_SATA_QDMA_PORT_RESET        = 0x08,
+    K2_SATA_QDMA_PORT_ABORT        = 0x04,
+    K2_SATA_QDMA_PORT_PAUSE        = 0x02,
+    K2_SATA_CLEAR_QDMA_QPI_REG     = 0x00,
+
+    K2_SATA_INTR_CMD_ERROR         = 0x00000020,
+    K2_SATA_INTR_DEV_CHANGE        = 0x10,
+    K2_SATA_INTR_RESET_ACK         = 0x08,
+    K2_SATA_INTR_ABORT_ACK         = 0x04,
+    K2_SATA_INTR_PAUSE_ACK         = 0x02,
+    K2_SATA_INTR_CMD_DONE          = 0x00000001,
+
+    K2_SATA_DESC_TYPE                          = 0x00,
+    K2_SATA_DESC_PIO_DATA                      = 0x00,
+    K2_SATA_DESC_PIO_NON_DATA                  = 0x02,
+
+    K2_SATA_CTRL_FLAG_PIO_BIT          = 0x80,     // PIO bit
+       K2_SATA_CTRL_FLAG_ATAPI                 = 0x40,         // ATAPI
bit
+       K2_SATA_CTRL_FLAG_SKIP                  = 0x10,         // SKIP
bit
+       K2_SATA_CTRL_FLAG_IGNR                  = 0x08,         // IGNR
bit
+       K2_SATA_CTRL_FLAG_RD_DIR_BIT    = 0x02,     // READ Dir bit
+    K2_SATA_CTRL_FLAG_EIN_BIT          = 0x01,     // Enable Interrupt
bit
+
+    K2_SATA_DESC_D_BIT                 = 0x01,
+    K2_CMD_ONLY_FRM                                    = 0x010,    /*
No data associated with command */
+
+       K2_ATAPI_CDB_BUFSZ                              = ATAPI_CDB_LEN,
+
+       K2_SATA_SELECT_DEV0                             = 0xA0,
+    K2_SATA_CMD_DEVICE_RESET           = 0x08,
+    K2_SATA_STS_BSY                    = 0x80,     // busy
+
+    K2_SATA_SCR2_RESET_PHY             = 0x00000001,
+    K2_SATA_SCR2_CLEAR_REG             = 0x00000000,
+
+    K2_SATA_DET_MASK                   = 0x000F,
+    K2_SATA_INTF_MASK                  = 0x0F00,
+    K2_DEV_DET_PHY_RDY                 = 0x3,
+    K2_SATA_INFT_ACTIVE                = 0x1,
+
+    K2_SATA_10MS_WAIT                  = 10000,
+    K2_SATA_100MS_WAIT                 = 100000,
+    K2_SATA_PAUSE_ACK_TIME             = 100,
+    K2_SATA_CLEAR_ALL_ERRORS           = 0xffffffff,
+    K2_SATA_COM_RESET_WAIT             = 1500,     //1.5ms
+
+    K2_SATA_QSR_PCI_MASTER_ABORT       = (1<<21),
+    K2_SATA_QSR_DATA_CRC_ERR           = (1<<20),
+    K2_SATA_QSR_UNDER_FLOW             = (1<<19),
+    K2_SATA_QSR_OVER_FLOW              = (1<<18),
+    K2_SATA_QSR_ATA_CMD_ERR            = (1<<17),
+    K2_SATA_QSR_PCI_BUS_MASTER_ERR     = (1<<16),
+    K2_SATA_QSR_SATA_INTF_ERR          = (1<<6),
+       K2_SATA_QSR_ATAPI_UNDERRUN              = (1<<22),
+
+       chip_svw4                       = 0,
+       chip_svw8                       = 1,
+       chip_svwx                       = 2,
+       chip_svw41                      = 3,
+// ATAPI QDMA end
+
+// HT1100 additions
+    K2_SATA_SATADBGREG               = 0xF0,
+    // K2_SATA_LEDENREG                = 0x5000,
+    K2_SATA_TESTCTRLREG                = 0x10f0,
+    K2_SATA_MDIOCTRLREG                = 0x8c,
+    // K2_SATA_PLLCTRLREG              = 0x84,
+
+    K2_SATA_PLL_WAIT                   = 990,//100000,//90000,
+    K2_SATA_LED_ENABLE_VALUE           = 0x00000002,
+    K2_SATA_TEST_CTRL_VALUE            = 0x40000001,
+    K2_SATA_PLL_CTRL_VALUE             = 0x08000000,
+    K2_SATA_PLL_1P5_GIG                                = 0,
+    K2_SATA_PLL_3P0_GIG                                = 1,
+    K2_SATA_RESET_PHY_DELAY            = 0x3000,
+
+       // phy vals
+    BCM_SATA_PHY_TXCNT_1G5  = 0x7830,
+    BCM_SATA_PHY_TXCNT_3G0  = 0xF620,
+    BCM_SATA_PHY_RXCNT_1G5  = 0x0180,
+    BCM_SATA_PHY_RXCNT_3G0  = 0x0190,
+
+       chip_svw42                      = 4,    // HT1100 bar 3
+       chip_svw43                      = 5,    // HT1100 bar 5
+       // HT1100 addns end
+
 };
 
+/* SATA Command Descriptor Structure */
+
+typedef struct _k2_sata_cmd_desc_s {
+#ifdef __BIG_ENDIAN
+    u8              ss_Rsvd3;
+    u8              ss_PortMul;
+    u8              ss_CtrlFlags;
+    u8              ss_DescType;
+    u16             sw_Tag;
+    u16             sw_HostMemDataBuffAddr;
+    u32             sl_PrdTblBaseLow;
+    u16             sw_PrdCount;
+    u16             sw_PrdTblBaseHigh;
+    u16             sw_Features;
+    u8              ss_DevHead;
+    u8              ss_SataCmd;
+    u32             sl_LbaLow;
+    u16             sw_SectorCount;
+    u16             sw_LbaHigh;
+    u32             sl_Rsvd1c;
+#else
+    u8              ss_DescType;
+    u8              ss_CtrlFlags;
+    u8              ss_PortMul;
+    u8              ss_Rsvd3;
+    u16             sw_HostMemDataBuffAddr;
+    u16             sw_Tag;
+    u32             sl_PrdTblBaseLow;
+    u16             sw_PrdTblBaseHigh;
+    u16             sw_PrdCount;
+    u8              ss_SataCmd;
+    u8              ss_DevHead;
+    u16             sw_Features;
+    u32             sl_LbaLow;
+    u16             sw_LbaHigh;
+    u16             sw_SectorCount;
+    u32             sl_Rsvd1c;
+#endif
+} k2_sata_cmd_desc_t;
+
+
+typedef struct _k2_sata_port_info_s {
+    u8      qpi;
+    u8      qci;
+    u8      qdma_mode;
+    u32     qcr_local;
+
+    // qdma related addrs
+    void __iomem    *qal_addr;
+    void __iomem    *qau_addr;
+    void __iomem    *qpi_addr;
+    void __iomem    *qci_addr;
+    void __iomem    *qcr_addr;
+    void __iomem    *qdr_addr;
+    void __iomem    *qsr_addr;
+    void __iomem    *qmr_addr;
+
+    // desc area and addresses
+    dma_addr_t      cmd_desc_addr;
+    k2_sata_cmd_desc_t* pcmd_desc;
+
+    dma_addr_t      cdb_phy_addr;
+    u8              *pcdb_cpybuf;
+
+    u8  needs_reset;
+
+    // atapi related
+    u8  is_atapi_device;
+    u32 qsr_saved;
+    u32 atapi_reset_cnt;
+    u32 atapi_capabilities;
+
+} k2_sata_port_info;
+
+
+int skip_init = 0;
+module_param(skip_init, int, 0444);
+MODULE_PARM_DESC( skip_init, "Initialization done by BIOS");
+
+
 static u8 k2_stat_check_status(struct ata_port *ap);
 
 
 static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
 {
+       u8 command = qc->scsicmd->cmnd[0];
+
        if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
                return -1;      /* ATAPI DMA not supported */
+       else
+       {
+               // DMA is for only read or write commands
+               if( (command == READ_10) || (command == READ_16) ||
(command == READ_12)
+                       || (command == WRITE_10) || (command ==
WRITE_16) || (command == WRITE_12))
+                       // TODO may need to check the dynamic flag in
pspi rather than unconditional ok
+                       return 0;
+               else
+                       return -1;
+       }
 
        return 0;
 }
@@ -305,6 +507,612 @@ static int k2_sata_proc_info(struct Scsi
 }
 #endif /* CONFIG_PPC_OF */
 
+// ATAPI QDMA start
+
+#define K2_IS_SATA_STS_GOOD(sata_sts)      \
+    (((sata_sts & K2_SATA_DET_MASK) == K2_DEV_DET_PHY_RDY) &&
(((sata_sts & K2_SATA_INTF_MASK)>>8) == K2_SATA_INFT_ACTIVE))
+
+
+void k2_ht1x_qdma_disable(struct ata_port *ap);
+
+
+int k2_ht1x_port_start (struct ata_port *ap)
+{
+       struct device *dev = ap->dev;
+       int rc;
+       k2_sata_port_info* pspi;
+       ap->private_data = NULL;
+
+       rc = ata_port_start( ap);
+       if( rc)
+               return rc;
+
+       // do our qdma descriptor space alloc, we use prd from ata port
itself
+       pspi = kmalloc(sizeof(k2_sata_port_info), GFP_KERNEL);
+       if (pspi == NULL) {
+               rc = -ENOMEM;
+               goto start_err_out;
+       }
+
+       ap->private_data = pspi;
+
+       pspi->pcmd_desc = dma_alloc_coherent(dev, sizeof(
k2_sata_cmd_desc_t) * K2_SATA_NUM_DESCRIPTORS, &pspi->cmd_desc_addr,
GFP_KERNEL);
+       if (pspi->pcmd_desc == NULL) {
+               kfree( pspi);
+               rc = -ENOMEM;
+               goto start_err_out;
+       }
+
+       pspi->pcdb_cpybuf = dma_alloc_coherent(dev, K2_ATAPI_CDB_BUFSZ,
&pspi->cdb_phy_addr, GFP_KERNEL);
+       if (pspi->pcdb_cpybuf == NULL) 
+       {
+               dma_free_coherent(dev, sizeof( k2_sata_cmd_desc_t) *
K2_SATA_NUM_DESCRIPTORS, pspi->pcmd_desc, pspi->cmd_desc_addr);
+               kfree( pspi);
+               rc = -ENOMEM;
+               goto start_err_out;
+       }
+
+       // data_addr is at 0 offset
+       pspi->qal_addr = ap->ioaddr.data_addr + K2_SATA_QAL_OFFSET;
+       pspi->qau_addr = ap->ioaddr.data_addr + K2_SATA_QAU_OFFSET;
+       pspi->qpi_addr = ap->ioaddr.data_addr + K2_SATA_QPI_OFFSET;
+       pspi->qci_addr = ap->ioaddr.data_addr + K2_SATA_QCI_OFFSET;
+       pspi->qcr_addr = ap->ioaddr.data_addr + K2_SATA_QCR_OFFSET;
+       pspi->qdr_addr = ap->ioaddr.data_addr + K2_SATA_QDR_OFFSET;
+       pspi->qsr_addr = ap->ioaddr.data_addr + K2_SATA_QSR_OFFSET;
+       pspi->qmr_addr = ap->ioaddr.data_addr + K2_SATA_QMR_OFFSET;
+
+       VPRINTK("svw qal 0x%x qsr addr 0x%x ioaddr 0x%x\n",
pspi->qal_addr, pspi->qsr_addr, ap->ioaddr.data_addr);
+
+       // init our stuff
+       pspi->qpi = 0;
+       pspi->qci = 0;
+       pspi->qdma_mode = 0;
+
+       writeb( 0, pspi->qci_addr);
+       writeb( 0, pspi->qpi_addr);
+       pspi->qcr_local = 0;
+       writel( pspi->qcr_local, pspi->qcr_addr);
+       writel( K2_SATA_CLEAR_ALL_INTRS, pspi->qsr_addr);
+
+       // writel( K2_SATA_ENABLE_INTRS, pspi->qmr_addr);
+       writel( K2_SATA_NUM_DESCRIPTORS - 1, pspi->qdr_addr);
+
+       pspi->needs_reset = 0;  
+       pspi->is_atapi_device = 0;      // will be set anytime we get a
atapi cmd on the port
+       pspi->atapi_reset_cnt = 0;
+       pspi->atapi_capabilities = 0;           // if v need to disable
dma on the fly becoz of too many errors etc
+
+       return 0;
+
+start_err_out:
+
+       return rc;
+}
+
+void k2_ht1x_port_stop (struct ata_port *ap)
+{
+       struct device *dev = ap->dev;
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       if( pspi == NULL)
+               return;
+
+       k2_ht1x_qdma_disable( ap);
+
+       // free our private data first, then call generic
+       dma_free_coherent(dev, sizeof( k2_sata_cmd_desc_t) *
K2_SATA_NUM_DESCRIPTORS, pspi->pcmd_desc, pspi->cmd_desc_addr);
+       dma_free_coherent(dev, K2_ATAPI_CDB_BUFSZ, pspi->pcdb_cpybuf,
pspi->cdb_phy_addr);
+       kfree( pspi);
+
+}
+
+/*
+       Some helper functions
+*/
+
+void k2_ht1x_qdma_enable(struct ata_port *ap)
+{
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       pspi->qpi = 0;
+       pspi->qci = 0;
+
+       pspi->qcr_local = K2_SATA_QDMA_ENABLE;
+
+       writel( cpu_to_le32(pspi->cmd_desc_addr & 0xffffffff),
pspi->qal_addr);
+       
+       // our dma mask is 32bit, so v assume 0 for upper bits
+       // similar to what libata does for prd addresses
+       // as below causes grief in 32bit single CPU flavour
+       // writel( cpu_to_le32( (pspi->cmd_desc_addr >> 32) & 0xffff),
pspi->qau_addr);
+       writel( 0, pspi->qau_addr);
+
+       writeb( 0, pspi->qci_addr);
+       writeb( 0, pspi->qpi_addr);
+       writel( K2_SATA_CLEAR_ALL_INTRS, pspi->qsr_addr);
+       writel( K2_SATA_NUM_DESCRIPTORS - 1, pspi->qdr_addr);
+
+       writel( K2_SATA_ENABLE_INTRS, pspi->qmr_addr);
+       writel( pspi->qcr_local, pspi->qcr_addr);
+
+
+}
+
+void k2_ht1x_qdma_disable(struct ata_port *ap)
+{
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       // disable qdma first
+       pspi->qcr_local = 0;
+       writel( pspi->qcr_local, pspi->qcr_addr);
+
+       pspi->qpi = 0;
+       pspi->qci = 0;
+       pspi->qdma_mode = 0;
+
+       writeb( 0, pspi->qci_addr);
+       writeb( 0, pspi->qpi_addr);
+       writel( K2_SATA_CLEAR_ALL_INTRS, pspi->qsr_addr);
+       writel( 0, pspi->qmr_addr);
+       writel( 0, pspi->qdr_addr);
+
+}
+
+int k2_ht1x_qdma_pause(struct ata_port *ap, int pause)
+{
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+       u32 qsr;
+       volatile int i = 0;
+
+       // if qdma is not enabled nothing todo, pause or unpause
+       if( !(pspi->qcr_local & K2_SATA_QDMA_ENABLE) )
+               return 0;
+
+       // pause qdma first, 
+       // disable intr on pause ack, we will poll for it as we don't q
cmds
+       if( !(pspi->qcr_local & K2_SATA_QDMA_PORT_PAUSE) && pause)
+       {
+               pspi->qcr_local |= K2_SATA_QDMA_PORT_PAUSE;
+               writel( pspi->qcr_local, pspi->qcr_addr);
+
+               // wait for pause ack
+               while( i++ < 200)
+               {
+                       udelay( 5);
+
+                       if( (qsr = readl( pspi->qsr_addr)) &
K2_SATA_INTR_PAUSE_ACK)
+                       {
+                               writel( qsr, pspi->qsr_addr);
+                               break;
+                       }
+               }
+
+               if( i == 200)
+               {
+                       pspi->qcr_local &= ~K2_SATA_QDMA_PORT_PAUSE;
+                       return -1;      // we couldn't pause in 10
msecs, we have problems.....
+               }
+
+       }
+       else
+       //  we need to unpause
+       if( (pspi->qcr_local & K2_SATA_QDMA_PORT_PAUSE) && !pause)
+       {
+
+               pspi->qcr_local &= ~K2_SATA_QDMA_PORT_PAUSE;
+               writel( pspi->qcr_local, pspi->qcr_addr);
+       }
+
+       return 0;
+}
+
+
+int k2_build_atapi_cmd_desc(struct ata_queued_cmd *qc,
k2_sata_cmd_desc_t *desc, u8 flags)
+{
+       struct ata_port *ap = qc->ap;
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       memset(desc, 0, sizeof(k2_sata_cmd_desc_t));
+
+       desc->ss_CtrlFlags = flags;
+       desc->ss_SataCmd = 0xA0;        // ATAPI Pkt Cmd
+       desc->ss_DevHead = 0xA0;
+
+       // as per libata atapi_xlat func, this is set for only pio
+       desc->sl_LbaLow = 0;
+       desc->sw_LbaHigh = 0;
+
+       if (flags & K2_SATA_CTRL_FLAG_ATAPI) 
+       {
+               // ATAPI CDB Packet Transfer
+               // Set the CDB pad to zero
+               memset(pspi->pcdb_cpybuf, 0, K2_ATAPI_CDB_BUFSZ);
+               memcpy(pspi->pcdb_cpybuf, qc->cdb, qc->dev->cdb_len);
+
+               desc->sl_PrdTblBaseLow = cpu_to_le32( pspi->cdb_phy_addr
| 0x01);
+               desc->sw_PrdTblBaseHigh = 0;
+               desc->sw_PrdCount = qc->dev->cdb_len;
+               desc->sw_Features = K2_ATAPI_FEAT_DMA_BIT;
+       } 
+       else    // it is the data desc
+       {
+               // libata does not update this field when splitting
prd's for 64kb crossover
+               // so examine eot bit in first prd element to confirm
+               // if(qc->n_elem == 1) {
+               if( (ap->prd[0].flags_len & cpu_to_le32(ATA_PRD_EOT) )
!= 0) {
+                       desc->sl_PrdTblBaseLow    = ap->prd[0].addr |
0x01;   // already in le format
+                       desc->sw_PrdTblBaseHigh   = 0;  // revisit to
add >4GB support, ata_fill_sg can't be used then
+                       desc->sw_PrdCount         = ap->prd[0].flags_len
& 0xFFFF;
+
+               }
+               else
+               {
+                       desc->sl_PrdTblBaseLow    =
cpu_to_le32(ap->prd_dma);
+                       desc->sw_PrdTblBaseHigh   = 0;  // v reuse same
prd table everytime
+               }
+
+       }
+
+       return 0;
+}
+
+void k2_ht1x_qdma_post_atapi(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       u8 flags = 0;
+
+       k2_sata_cmd_desc_t* pcdesc = pspi->pcmd_desc + pspi->qpi;
+
+       flags  = K2_SATA_CTRL_FLAG_ATAPI | K2_SATA_CTRL_FLAG_PIO_BIT;
//  | K2_SATA_CTRL_FLAG_EIN_BIT;
+       k2_build_atapi_cmd_desc( qc, pcdesc, flags);
+
+       flags = K2_SATA_CTRL_FLAG_EIN_BIT;
+
+       if( !(qc->tf.flags & ATA_TFLAG_WRITE) ) 
+               flags |= K2_SATA_CTRL_FLAG_RD_DIR_BIT;
+       pcdesc++;
+       k2_build_atapi_cmd_desc( qc, pcdesc, flags);
+
+       pspi->qpi = (pspi->qpi + 2) % K2_SATA_NUM_DESCRIPTORS;
+
+       writel( pspi->qpi, pspi->qpi_addr);
+
+
+}
+
+
+/*
+later version of libata (kernel 2.6.18 & later) have a elaborate
+error handling mech that includes multilevel of resets (soft, hard,
post...)  
+so we plug into that
+
+*/
+int k2_ht1x_atapi_soft_reset(struct ata_port *ap, unsigned int *class)
+{
+       u8      dev_sts;
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       int count = 5;
+
+       writel( K2_SATA_SELECT_DEV0, ioaddr->device_addr );
+       udelay( 500);
+       writel( K2_SATA_CMD_DEVICE_RESET, ioaddr->command_addr );
+
+       // this can take upto 5 secs
+       do
+       {
+               dev_sts = ata_busy_wait( ap, 100000, K2_SATA_STS_BSY);
+               count--;
+       } while( ( dev_sts & K2_SATA_STS_BSY) && (count > 0) );
+
+       if (dev_sts & K2_SATA_STS_BSY) {
+               printk("sata_svw : Busy still set after soft reset
dev_sts=%x\n", dev_sts);
+               return -EIO;
+       }
+
+       *class = ata_dev_try_classify(ap, 0, NULL);
+       return 0;
+}
+
+
+int k2_ht1x_atapi_reset(struct ata_port *ap, unsigned int *class)
+{
+       u32     dev_sts, sata_sts, qsr, i;
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+       int ret = 0;
+       
+
+       // if (port->atapi.capabilities & ELR_ATAPI_QDMA) 
+       {
+               k2_ht1x_qdma_disable( ap);
+
+               // Do a PHY reset 
+               // Power Down Phy
+               k2_sata_scr_write( ap, (K2_SATA_SCR_CONTROL_OFFSET -
K2_SATA_SCR_STATUS_OFFSET), K2_SATA_SCR2_RESET_PHY );
+               // Delay 1.5ms
+               udelay( K2_SATA_COM_RESET_WAIT);
+               // Power Up Phy
+               k2_sata_scr_write( ap, (K2_SATA_SCR_CONTROL_OFFSET -
K2_SATA_SCR_STATUS_OFFSET), K2_SATA_SCR2_CLEAR_REG );
+               // Delay 1ms : Most drives should be ready within 1ms
+               udelay( K2_SATA_COM_RESET_WAIT);
+               //  delay up to 2 seconds, this should be ok for SATA I
and SATA II drives
+               for (i = 0; i < 20; i++) {
+                       //  check if drive exist again
+                       k2_sata_scr_read( ap, 0, &sata_sts );
+                       dev_sts = k2_stat_check_status( ap);
+                       //  drive exist and ready
+                       if (K2_IS_SATA_STS_GOOD(sata_sts) && (!(dev_sts
& K2_SATA_STS_BSY))) {
+                               //  Initialize Registers
+                               k2_sata_scr_write( ap,
(K2_SATA_SCR_ERROR_OFFSET - K2_SATA_SCR_STATUS_OFFSET),
K2_SATA_CLEAR_ALL_ERRORS );
+                               qsr = readl( pspi->qsr_addr);
+                               writel( qsr, pspi->qsr_addr);
+       
+                               VPRINTK( "PHY Reset on Port[%x] i=%x
DrvSts=%x SataSts=%x SUCCESSFULLY Completed\n",
+                                       ap->port_no, i, dev_sts,
sata_sts);
+                               break;
+                       }
+                       //  check every 1 milli second, most of the
drive will be ready in a milli second
+                       msleep( K2_SATA_100MS_WAIT / 1000);
+               }
+               if (i == 20) {
+                       DPRINTK("\n\nPHY Reset on Port[%x] DrvSts=%x
SataSts=%x FAILED\n\n",
+                               ap->port_no, dev_sts, sata_sts);
+                       ret = -EIO;
+               }
+
+               // QDMA Reset
+        writel( (K2_SATA_QDMA_PORT_RESET|K2_SATA_QDMA_ENABLE),
pspi->qcr_addr);
+        // Wait for the Reset ack
+               for (i = 0; i < K2_SATA_PAUSE_ACK_TIME; i++) {
+                       qsr = readl( pspi->qsr_addr);
+                       if (qsr & K2_SATA_INTR_RESET_ACK) break;
+                       udelay( K2_SATA_10MS_WAIT);
+               }
+        if (i == K2_SATA_PAUSE_ACK_TIME) {
+            printk("sata_svw : Port[%x] ATAPI Reset FAILED QSR=%x\n",
ap->port_no, qsr);
+                       ret = -EIO;
+        }
+
+               qsr = readl( pspi->qsr_addr);
+               writel( qsr, pspi->qsr_addr);
+               // Clear bit 5 in QSR if set
+               if (qsr & K2_SATA_INTR_CMD_ERROR)
+                       writel( qsr, pspi->qsr_addr);
+               k2_sata_scr_write( ap, (K2_SATA_SCR_ERROR_OFFSET -
K2_SATA_SCR_STATUS_OFFSET), K2_SATA_CLEAR_ALL_ERRORS );
+       }
+       
+       if( ret != 0)
+               return ret;
+
+
+       // Enable QDMA
+       k2_ht1x_qdma_enable( ap);
+
+       *class = ata_dev_try_classify(ap, 0, NULL);
+       return 0;
+}
+
+
+inline unsigned int k2_ht1x_handle_qdma_error (struct ata_port *ap,
+                                  struct ata_queued_cmd *qc, u32 qsr)
+{
+       u8 status;
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       k2_ht1x_qdma_pause( ap, 1);
+       DPRINTK("qdma atapi error 0x%x\n", qsr);
+
+       // all tf registers specifically sts maintain their contents, so
fall into libata's complete fn
+       if( qsr & K2_SATA_QSR_PCI_BUS_MASTER_ERR)
+       {
+               qc->err_mask |= AC_ERR_HOST_BUS;
+               ap->hsm_task_state = HSM_ST_ERR;
+       }
+
+       status = k2_stat_check_status( ap);
+
+       if( (qsr & K2_SATA_QSR_OVER_FLOW) || ( pspi->qci != pspi->qpi) )
+       {
+               printk( "sata_svw needs_reset=1 qsr 0x%x\n", qsr);
+               pspi->qsr_saved = qsr;
+               pspi->needs_reset = 1;
+               qc->err_mask |= AC_ERR_HSM;             
+               // this will freeze the port & ops->error_handler is
then invoked to thaw the port
+               // and do other bad things like reset (hard, soft) etc
+       }
+
+       ata_hsm_move( ap, qc, status, 0);
+       return 0;
+
+}
+
+inline unsigned int k2_ht1x_qdma_intr (struct ata_port *ap,
+                                  struct ata_queued_cmd *qc)
+{
+       u32 qsr;
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       VPRINTK("ata%u: protocol %d task_state %d\n",
+               ap->id, qc->tf.protocol, ap->hsm_task_state);
+
+       /* Check whether we are expecting interrupt in this state */
+       switch (ap->hsm_task_state) {
+       case HSM_ST_LAST:
+               if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
+               {
+
+                       // do some qdma qsr processing here
+                       qsr = readl( pspi->qsr_addr);
+
+                       // check if there is an error, if not make sure
it is the done for the 2nd cmd
+                       writel( qsr, pspi->qsr_addr);
+                       pspi->qci = readl( pspi->qci_addr);
+                       if( qsr & K2_SATA_INTR_CMD_ERROR)
+                       {
+                               // clear qsr common error bit
+                               writel( qsr, pspi->qsr_addr);
+
+                               k2_ht1x_handle_qdma_error( ap, qc, qsr);
+                               return 1;       /* irq handled */
+                       }
+                       else
+                       {
+                               if( pspi->qci != pspi->qpi)
+                               {
+                                       printk("sata_svw STOP stuck
without error qsr 0x%x\n", qsr);
+                                       return 0;
+                               }
+
+
+                               // yay! v got a normal completion, let
us finish it
+                               ap->hsm_task_state = HSM_ST_IDLE;
+
+                               // for now just clear tf read flag,
hopefully it is used only in error path
+                               qc->flags &= ~ATA_QCFLAG_RESULT_TF;
+                               ata_qc_complete( qc);
+                               return 1;       /* irq handled */
+                       }
+               }
+               else
+                       printk("wrong protocol, we shouldn't hv been
here %d \n", qc->tf.protocol);
+               break;
+
+
+       default:
+               break;  // goto idle_irq;
+       }
+
+       return 0;       /* irq not handled */
+}
+
+
+irqreturn_t k2_ht1x_interrupt (int irq, void *dev_instance)
+{
+       struct ata_host *host = dev_instance;
+       unsigned int i;
+       unsigned int handled = 0;
+       unsigned long flags;
+       k2_sata_port_info* pspi;
+       u32 glbsts;
+       struct ata_port *ap;
+       struct ata_queued_cmd *qc;
+
+       /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
+       spin_lock_irqsave(&host->lock, flags);
+
+       ap = host->ports[0];
+       glbsts = readl( ap->ioaddr.data_addr + K2_SATA_GLB_STS_OFFSET);
+       for (i = 0; i < host->n_ports; i++) 
+       {
+               if( glbsts & (1 << i) )
+                       // '1' bit indicates no interrupt on this port,
keep moving
+                       continue;
+
+               ap = host->ports[i];
+
+               if (ap &&
+                   !(ap->flags & ATA_FLAG_DISABLED)) {
+                       pspi = (k2_sata_port_info*)ap->private_data;
+                       if( !pspi)
+                       {
+                               VPRINTK("pspi not set port %d \n", i);
+                               continue;
+                       }
+
+                       qc = ata_qc_from_tag(ap, ap->active_tag);
+                       if (qc && 
+                           (qc->flags & ATA_QCFLAG_ACTIVE))
+                       {
+                               if( (pspi->qcr_local &
K2_SATA_QDMA_ENABLE) &&
+                                               !(pspi->qcr_local &
K2_SATA_QDMA_PORT_PAUSE) )
+                                       handled |= k2_ht1x_qdma_intr(
ap, qc);
+                               else
+                               if( !(qc->tf.flags & ATA_TFLAG_POLLING))
+                                       // let libata's nice handler
take care of it
+                                       handled |= ata_host_intr(ap,
qc);
+                       }
+
+               }
+       }
+
+       spin_unlock_irqrestore(&host->lock, flags);
+
+       return IRQ_RETVAL(handled);
+}
+
+unsigned int k2_ht1x_qc_issue_prot(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       /* start the command */
+       switch (qc->tf.protocol) {
+
+       // ATA stuff fall through to libata
+       case ATA_PROT_NODATA:
+       case ATA_PROT_PIO:
+       case ATA_PROT_DMA:
+               pspi->is_atapi_device = 0;
+               return ata_qc_issue_prot( qc);
+               break;
+
+       case ATA_PROT_ATAPI:
+       case ATA_PROT_ATAPI_NODATA:
+               pspi->is_atapi_device = 1;
+               if( (pspi->qcr_local & K2_SATA_QDMA_ENABLE) && 
+                       !(pspi->qcr_local & K2_SATA_QDMA_PORT_PAUSE) )
+                       k2_ht1x_qdma_pause( ap, 1);
+
+               return ata_qc_issue_prot( qc);
+               break;
+
+
+       case ATA_PROT_ATAPI_DMA:
+               WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+               pspi->is_atapi_device = 1;
+
+               if( !(pspi->qcr_local & K2_SATA_QDMA_ENABLE) )
+                       k2_ht1x_qdma_enable( ap);
+               else
+               // unpause if needed
+               if( pspi->qcr_local & K2_SATA_QDMA_PORT_PAUSE)
+                       k2_ht1x_qdma_pause( ap, 0);
+
+               k2_ht1x_qdma_post_atapi( qc);
+
+               ap->hsm_task_state = HSM_ST_LAST;
+               break;
+
+       default:
+               WARN_ON(1);
+               return AC_ERR_SYSTEM;
+       }
+
+       return 0;
+}
+
+void k2_sata_error_handler(struct ata_port *ap)
+{
+       k2_sata_port_info* pspi = (k2_sata_port_info*)ap->private_data;
+
+       if( !pspi->is_atapi_device)
+       {
+               // let libata do all the hard work
+               ata_bmdma_error_handler( ap);
+               return;
+       }
+
+       // if we have atapi then likely we used qdma and hung on that
+       // so we use our soft & hardresets
+       ata_bmdma_drive_eh(ap, ata_std_prereset,
k2_ht1x_atapi_soft_reset, k2_ht1x_atapi_reset,
+                          ata_std_postreset);
+
+}
+
+// ATAPI QDMA end
+
 
 static struct scsi_host_template k2_sata_sht = {
        .module                 = THIS_MODULE,
@@ -346,6 +1154,7 @@ static const struct ata_port_operations 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = ata_bmdma_error_handler,
+       .irq_handler            = ata_interrupt,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
@@ -355,8 +1164,42 @@ static const struct ata_port_operations 
        .port_start             = ata_port_start,
 };
 
+// ATAPI QDMA start
+
+static const struct ata_port_operations k2_ht1x_ops = {
+       .port_disable           = ata_port_disable,
+       .tf_load                = k2_sata_tf_load,
+       .tf_read                = k2_sata_tf_read,
+       .check_status           = k2_stat_check_status,
+       .exec_command           = ata_exec_command,
+       .dev_select             = ata_std_dev_select,
+       .check_atapi_dma        = k2_sata_check_atapi_dma,
+       .bmdma_setup            = k2_bmdma_setup_mmio,
+       .bmdma_start            = k2_bmdma_start_mmio,
+       .bmdma_stop             = ata_bmdma_stop,
+       .bmdma_status           = ata_bmdma_status,
+       .qc_prep                = ata_qc_prep,
+       .qc_issue               = k2_ht1x_qc_issue_prot,
+       .data_xfer              = ata_data_xfer,
+       .freeze                 = ata_bmdma_freeze,
+       .thaw                   = ata_bmdma_thaw,
+       .error_handler          = k2_sata_error_handler,
+       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .irq_handler            = k2_ht1x_interrupt,
+       .irq_clear              = ata_bmdma_irq_clear,
+       .irq_on                 = ata_irq_on,
+       .irq_ack                = ata_irq_ack,
+       .scr_read               = k2_sata_scr_read,
+       .scr_write              = k2_sata_scr_write,
+       .port_start             = k2_ht1x_port_start,
+       .port_stop              = k2_ht1x_port_stop,
+};
+
+// ATAPI QDMA end
+
+
 static const struct ata_port_info k2_port_info[] = {
-       /* board_svw4 */
+       /* chip_svw4 */
        {
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
@@ -365,7 +1208,7 @@ static const struct ata_port_info k2_por
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &k2_sata_ops,
        },
-       /* board_svw8 */
+       /* chip_svw8 */
        {
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
@@ -375,8 +1218,156 @@ static const struct ata_port_info k2_por
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &k2_sata_ops,
        },
+       /* chip_svwx */
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3, 
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &k2_ht1x_ops,
+       },
+       /* chip_svw41 */
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO, 
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &k2_ht1x_ops,
+       },
+       /* chip_svw42 */
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &k2_sata_ops,
+       },
+       /* chip_svw43 */
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &k2_sata_ops,
+       },
 };
 
+// HT1100 addns
+inline void k2_lnx_sleep( u32 usec_delay)
+{
+    (usec_delay > 1000) ? mdelay(usec_delay/1000 + 1):
udelay(usec_delay);
+}
+
+ 
+#define K2_SATA_WAIT_MDIO_DONE(reg)       \
+{   \
+    u32     tmp_reg, to = 1000; \
+    while (to) {    \
+        tmp_reg = cpu_to_le32( readl(reg) );   \
+        if (tmp_reg & (1 << 15)) {  \
+            break;  \
+        }   \
+        k2_lnx_sleep( 10);  \
+        to--;   \
+    }   \
+}
+ 
+#define K2_IS_SATA_STS_GOOD(sata_sts)      \
+    (((sata_sts & K2_SATA_DET_MASK) == K2_DEV_DET_PHY_RDY) &&
(((sata_sts & K2_SATA_INTF_MASK)>>8) == K2_SATA_INFT_ACTIVE))
+
+
+inline void k2_sata_port_reset_phy_start_oob( void __iomem
*mmio_port_base, u32 ul_satainitval)
+{
+    u32 oob_try = 0, sata_sts;
+
+    writel( ul_satainitval, (mmio_port_base + K2_SATA_SATADBGREG) );
+    k2_lnx_sleep( K2_SATA_RESET_PHY_DELAY);
+
+    // Retry oob up to 5 times
+    do {
+        writel( K2_SATA_SCR2_RESET_PHY, (mmio_port_base +
K2_SATA_SCR_CONTROL_OFFSET) );
+        k2_lnx_sleep( K2_SATA_RESET_PHY_DELAY);
+
+        writel( K2_SATA_SCR2_CLEAR_REG, (mmio_port_base +
K2_SATA_SCR_CONTROL_OFFSET) );
+        k2_lnx_sleep( K2_SATA_RESET_PHY_DELAY);
+
+        sata_sts = readl( mmio_port_base + K2_SATA_SCR_STATUS_OFFSET);
+    } while ((!K2_IS_SATA_STS_GOOD(sata_sts)) && (++oob_try < 5));
+
+}
+
+ 
+inline void k2_sata_pll_init(void __iomem *mmio_base, u32 link_rate,
u32 portnum)
+{
+    u32     ul_PortSelect=0;
+    u32     ul_initval, ul_voltval, mdioctrl;
+ 
+ 
+    /* MDIO access is accessible only through Port 0, so we take mmio
base as input */
+ 
+    // Enable MDIO Space
+    writel( K2_SATA_TEST_CTRL_VALUE, ( mmio_base + K2_SATA_TESTCTRLREG)
);
+    k2_lnx_sleep( K2_SATA_PLL_WAIT);
+ 
+    /* mdio reg: 31:16  - r/w data
+     *           15     - done
+     *           14:13  - r(10) w(01)
+     *           12:8   - device address
+     *           7:5    - res
+     *           4:0    - reg addr
+     */
+
+       // pll workaround
+    writel( 0x4002, (mmio_base + K2_SATA_MDIOCTRLREG));
+    K2_SATA_WAIT_MDIO_DONE(mmio_base + K2_SATA_MDIOCTRLREG);
+       mdioctrl = readl( mmio_base + K2_SATA_MDIOCTRLREG) >> 16;
+       // clear bit 2
+       mdioctrl &= ~0x04;
+       mdioctrl = mdioctrl << 16;
+    writel( mdioctrl | 0x2002, (mmio_base + K2_SATA_MDIOCTRLREG));
+    K2_SATA_WAIT_MDIO_DONE(mmio_base + K2_SATA_MDIOCTRLREG);
+
+
+    ul_PortSelect = (((1 << portnum) << 16) | (0x2007));
+ 
+    if (link_rate == K2_SATA_PLL_1P5_GIG) 
+       {
+        //550 mV (Main Driver), 0% pre-emphasis, 0% Bias for SATA 1.5G
: voltval=0x7830
+        ul_voltval = (BCM_SATA_PHY_TXCNT_1G5 << 16) | 0x200a;
+        ul_initval = (BCM_SATA_PHY_RXCNT_1G5 << 16) | 0x2008;
+    } 
+       else 
+       {
+        //750 mV (Main Driver), 20% pre-emphasis, 0% Bias for 3G :
voltval=0xF620
+        ul_voltval = (BCM_SATA_PHY_TXCNT_3G0 << 16) | 0x200a;
+        ul_initval = (BCM_SATA_PHY_RXCNT_3G0 << 16) | 0x2008;
+    }
+ 
+    writel( ul_PortSelect, (mmio_base + K2_SATA_MDIOCTRLREG));
+    K2_SATA_WAIT_MDIO_DONE(mmio_base + K2_SATA_MDIOCTRLREG);
+ 
+    writel( ul_initval, (mmio_base + K2_SATA_MDIOCTRLREG));
+    K2_SATA_WAIT_MDIO_DONE(mmio_base + K2_SATA_MDIOCTRLREG);
+ 
+    writel( ul_voltval, (mmio_base + K2_SATA_MDIOCTRLREG));
+    K2_SATA_WAIT_MDIO_DONE(mmio_base + K2_SATA_MDIOCTRLREG);
+ 
+    // Disable MDIO Access
+    mdioctrl = readl( mmio_base + K2_SATA_TESTCTRLREG);
+    mdioctrl &= (~K2_SATA_TEST_CTRL_VALUE);
+    writel( mdioctrl | 0x01, (mmio_base + K2_SATA_TESTCTRLREG) );
+    k2_lnx_sleep( K2_SATA_PLL_WAIT);
+ 
+}
+
+// HT1100 end
+
+
+
 static void k2_sata_setup_port(struct ata_ioports *port, void __iomem
*base)
 {
        port->cmd_addr          = base + K2_SATA_TF_CMD_OFFSET;
@@ -399,12 +1390,12 @@ static void k2_sata_setup_port(struct at
 
 static int k2_sata_init_one (struct pci_dev *pdev, const struct
pci_device_id *ent)
 {
-       static int printed_version;
+       static int printed_version = 0;
        const struct ata_port_info *ppi[] =
                { &k2_port_info[ent->driver_data], NULL };
        struct ata_host *host;
        void __iomem *mmio_base;
-       int n_ports, i, rc;
+       int n_ports, i, rc, bar_pos;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version "
DRV_VERSION "\n");
@@ -418,6 +1409,10 @@ static int k2_sata_init_one (struct pci_
        if (!host)
                return -ENOMEM;
 
+       bar_pos = 5;
+       if (ppi[0]->flags & K2_FLAG_BAR_POS_3)
+               bar_pos = 3;
+
        /*
         * If this driver happens to only be useful on Apple's K2, then
         * we should check that here as it has a normal Serverworks ID
@@ -430,25 +1425,51 @@ static int k2_sata_init_one (struct pci_
         * Check if we have resources mapped at all (second function may
         * have been disabled by firmware)
         */
-       if (pci_resource_len(pdev, 5) == 0)
+       if (pci_resource_len(pdev, bar_pos) == 0)
                return -ENODEV;
 
        /* Request and iomap PCI regions */
-       rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+       // rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+       rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME);
        if (rc == -EBUSY)
                pcim_pin_device(pdev);
        if (rc)
                return rc;
        host->iomap = pcim_iomap_table(pdev);
-       mmio_base = host->iomap[5];
+       mmio_base = host->iomap[bar_pos];
 
        /* different controllers have different number of ports -
currently 4 or 8 */
        /* All ports are on the same function. Multi-function device is
no
         * longer available. This should not be seen in any system. */
        for (i = 0; i < host->n_ports; i++)
+       {
+// HT1100 addns start
+               if( ent->device == 0x0410)
+               {
+                       if( !skip_init)
+                       {
+                               // set mode, phy vals etc
+                               // ht1100 needs a global phy enable bit,
so we do that for port zero iteration
+                               if( i == 0)
+                                       writel( readl( mmio_base +
0x10F0) | 0x01, (mmio_base + 0x10F0) );
+
+                               k2_sata_pll_init( mmio_base,
K2_SATA_PLL_1P5_GIG, i);
+
+                               k2_sata_port_reset_phy_start_oob(
mmio_base + (i * K2_SATA_PORT_OFFSET), 0x10100 );
+
+                       }
+
+                       writel( readl( mmio_base + (i *
K2_SATA_PORT_OFFSET) + 0x84) | 0x2000f800, (mmio_base + (i *
K2_SATA_PORT_OFFSET) + 0x84) );
+                       writel( readl( mmio_base + (i *
K2_SATA_PORT_OFFSET) + 0xE0) | 0x2, (mmio_base + (i *
K2_SATA_PORT_OFFSET) + 0xE0) );
+               }
+// HT1100 addns end
+
                k2_sata_setup_port(&host->ports[i]->ioaddr,
                                   mmio_base + i * K2_SATA_PORT_OFFSET);
 
+       }
+
+
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
                return rc;
@@ -468,7 +1489,7 @@ static int k2_sata_init_one (struct pci_
        writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
 
        pci_set_master(pdev);
-       return ata_host_activate(host, pdev->irq, ata_interrupt,
IRQF_SHARED,
+       return ata_host_activate(host, pdev->irq,
ppi[0]->port_ops->irq_handler, IRQF_SHARED,
                                 &k2_sata_sht);
 }
 
@@ -477,14 +1498,19 @@ static int k2_sata_init_one (struct pci_
  * 0x242 is device ID for Serverworks Frodo8
  * 0x24a is device ID for BCM5785 (aka HT1000) HT southbridge
integrated SATA
  * controller
+ * 0x41x is device ID for HT1100 southbridge integrated SATA storage
controller
  * */
 static const struct pci_device_id k2_sata_pci_tbl[] = {
-       { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
-       { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
-       { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
-       { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
-       { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },
-
+       { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 },
+       { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 },
+       { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 },
+// ATAPI QDMA start                                            
+       { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw41 },
+       { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw41 },
+       { PCI_VDEVICE(SERVERWORKS, 0x024c), chip_svw4 },
+// ATAPI QDMA end                                              
+       { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 },
+       { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 },
        { }
 };
 

-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to