[PATCH 2.6.23.11]: [sata_svw]: Add ATAPI DMA support for HT1x00 SATA controller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

Signed-off-by: Anantha Subramanyam <ananth@xxxxxxxxxxxx>
---
--- 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux