diff -uNr linux-2.6.13.4.orig/drivers/scsi/sata_sis.c linux-2.6.13.4/drivers/scsi/sata_sis.c
--- linux-2.6.13.4.orig/drivers/scsi/sata_sis.c	Mon Oct 10 20:54:29 2005
+++ linux-2.6.13.4/drivers/scsi/sata_sis.c	Tue Oct 18 01:10:52 2005
@@ -42,12 +42,16 @@
 
 enum {
 	sis_180			= 0,
+	sis_182			= 1,
 	SIS_SCR_PCI_BAR		= 5,
-
+	SIS_ALLOC_PRIV_SIZE	= 0x10,
 	/* PCI configuration registers */
 	SIS_GENCTL		= 0x54, /* IDE General Control register */
 	SIS_SCR_BASE		= 0xc0, /* sata0 phy SCR registers */
 	SIS_SATA1_OFS		= 0x10, /* offset from sata0->sata1 phy regs */
+	SIS_PMR			= 0x90, /* port mapping register */
+	SIS_CHANNEL_CTRL	= 0x50, /* primary channel control register */
+	ATA_DEV_RESET		= 0x08, /* Device Reset command */
 
 	/* random bits */
 	SIS_FLAG_CFGSCR		= (1 << 30), /* host flag: SCRs via PCI cfg */
@@ -58,10 +62,17 @@
 static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+static void sis_port_reset(struct ata_port *ap);
+static void sis_set_piomode (struct ata_port *ap, struct ata_device *dev);
+static void sis_set_dmamode (struct ata_port *ap, struct ata_device *dev);
+static int sis_port_start(struct ata_port *ap);
+static void sis_port_stop(struct ata_port *ap);
+static void sis_qc_prep(struct ata_queued_cmd *qc);
 
 static struct pci_device_id sis_pci_tbl[] = {
 	{ PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
 	{ PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
+	{ PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_182 },
 	{ }	/* terminate list */
 };
 
@@ -95,97 +106,523 @@
 
 static struct ata_port_operations sis_ops = {
 	.port_disable		= ata_port_disable,
+	.set_piomode		= sis_set_piomode,
+	.set_dmamode		= sis_set_dmamode,
 	.tf_load		= ata_tf_load,
 	.tf_read		= ata_tf_read,
 	.check_status		= ata_check_status,
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
-	.phy_reset		= sata_phy_reset,
-	.bmdma_setup            = ata_bmdma_setup,
+	.phy_reset		= sis_port_reset,
+	.bmdma_setup		= ata_bmdma_setup,
 	.bmdma_start            = ata_bmdma_start,
 	.bmdma_stop		= ata_bmdma_stop,
 	.bmdma_status		= ata_bmdma_status,
-	.qc_prep		= ata_qc_prep,
+	.qc_prep		= sis_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 	.eng_timeout		= ata_eng_timeout,
 	.irq_handler		= ata_interrupt,
 	.irq_clear		= ata_bmdma_irq_clear,
 	.scr_read		= sis_scr_read,
 	.scr_write		= sis_scr_write,
-	.port_start		= ata_port_start,
-	.port_stop		= ata_port_stop,
+	.port_start		= sis_port_start,
+	.port_stop		= sis_port_stop,
 	.host_stop		= ata_host_stop,
 };
 
 static struct ata_port_info sis_port_info = {
 	.sht		= &sis_sht,
-	.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
-			  ATA_FLAG_NO_LEGACY,
+	.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS |
+			  ATA_FLAG_NO_LEGACY,	
 	.pio_mask	= 0x1f,
 	.mwdma_mask	= 0x7,
 	.udma_mask	= 0x7f,
 	.port_ops	= &sis_ops,
 };
 
+struct sis_port_priv {
+	u32 addr;
+	u32 pad_phy_addr;
+};
 
 MODULE_AUTHOR("Uwe Koziolek");
 MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
-MODULE_VERSION(DRV_VERSION);
+MODULE_VERSION();
 
-static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
+
+void sis_qc_prep(struct ata_queued_cmd *qc)
 {
-	unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
+	struct scatterlist *sg = qc->sg;
+	struct ata_port *ap = qc->ap;
+	unsigned int idx, nelem;
+	struct sis_port_priv * sis_priv;
+	
+	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+		return;
+
+	assert(sg != NULL);
+	assert(qc->n_elem > 0);
 
-	if (port_no)
-		addr += SIS_SATA1_OFS;
-	return addr;
+	idx = 0;
+	for (nelem = qc->n_elem; nelem; nelem--,sg++) {
+		u32 addr, offset;
+		u32 sg_len, len;
+
+		/* determine if physical DMA addr spans 64K boundary.
+		 * Note h/w doesn't support 64-bit, so we unconditionally
+		 * truncate dma_addr_t to u32.
+		 */
+		addr = (u32) sg_dma_address(sg);
+		sg_len = sg_dma_len(sg);
+
+		while (sg_len) {
+			offset = addr & 0xffff;
+			len = sg_len;
+			if ((offset + sg_len) > 0x10000)
+				len = 0x10000 - offset;
+
+			ap->prd[idx].addr = cpu_to_le32(addr);
+			ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff);
+			VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
+
+			idx++;
+			sg_len -= len;
+			addr += len;
+		}
+	}
+
+	if (idx){
+		/** 
+			SATA transcation is DWORD unit, need to pad WORD for ODD-WORD request
+			for SiS controller
+		*/
+		if ((ap->prd[idx - 1].flags_len %4) != 0)
+		{
+			sis_priv = (struct sis_port_priv *)ap->private_data;
+			DPRINTK ("PRD[%u]_ADDR = 0x%X\n", idx-1, ap->prd[idx-1].addr);
+			DPRINTK ("PRD[%u]_LEN  = 0x%X\n", idx-1, ap->prd[idx-1].flags_len);
+			ap->prd[idx].addr = cpu_to_le32(sis_priv->pad_phy_addr);
+			ap->prd[idx].flags_len = 2|cpu_to_le32(ATA_PRD_EOT);
+			DPRINTK ("PRD[%u]_ADDR = 0x%X\n", idx, ap->prd[idx].addr);
+			DPRINTK ("PRD[%u]_LEN  = 0x%X\n", idx, ap->prd[idx].flags_len);
+		}
+		else {
+			ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+		}
+	}
 }
 
-static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+int sis_port_start(struct ata_port *ap)
 {
-	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
-	u32 val;
+	struct device *dev = ap->host_set->dev;
+	u8 * buf;
+	struct sis_port_priv * sis_priv;
+	
+	buf = kmalloc(SIS_ALLOC_PRIV_SIZE, GFP_KERNEL);
+	if (!buf) {
+		return -ENOMEM;
+	}
+	
+	sis_priv = (struct sis_port_priv *)buf;
+	ap->private_data = sis_priv;
+	// record the phy_addr of the padding buffer, offset by 4 from requested priv_data, for later use.
+	sis_priv->pad_phy_addr = dma_map_single(dev, buf+sizeof(u32), sizeof(u16), DMA_BIDIRECTIONAL);
+	ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
+	
+	if (!ap->prd){
+		kfree(buf);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void sis_port_stop(struct ata_port *ap)
+{
+	struct device *dev = ap->host_set->dev;
+	struct sis_port_priv * sis_priv = (struct sis_port_priv *)ap->private_data;
 
-	if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
-		return 0xffffffff;
-	pci_read_config_dword(pdev, cfg_addr, &val);
-	return val;
+	dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+	// umap the padding buffer.
+	dma_unmap_single(dev, sis_priv->pad_phy_addr, sizeof(u16), DMA_BIDIRECTIONAL);
+	kfree(ap->private_data);
 }
 
-static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
+
+static void sis_set_piomode (struct ata_port *ap, struct ata_device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
+	static const	 
+	u8 timings[][3]	= { { 9, 38, 40 },
+			    { 6, 38, 12 },
+			    { 3, 38,  4 },
+			    { 3, 10, 12 },
+			    { 3,  9,  5 } };
+	u32	val;
+	u8	reg = (dev->devno)?0x44:0x40;
+	
+	if (pdev->device == 0x182)
+		return;	
+	if (ap->port_no != 0)
+		return;	
+		
+	pci_read_config_dword(pdev, reg, &val);
+	val = (val & ~0xf000)     | (u32)timings[dev->pio_mode-8][0]<<12;
+	val = (val & ~0x3f0000)   | (u32)timings[dev->pio_mode-8][1]<<16;
+	val = (val & ~0x3f000000) | (u32)timings[dev->pio_mode-8][2]<<24;
+	pci_write_config_dword(pdev, reg, val);	
+  
+}
 
-	if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
+/*
+	Only 180/181 device need to set controller timing.
+*/
+static void sis_set_dmamode (struct ata_port *ap, struct ata_device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+	static const	 
+	u8 timings[][2]	= { { 15, 9 },
+					{ 10, 6 },
+					{  7, 4 },
+					{  5, 2 },
+					{  3, 2 },
+					{  2, 2 },
+					{  1, 2 } };
+	u32	val;
+	u8	reg = (dev->devno)?0x44:0x40;
+			    
+	if (pdev->device == 0x182)
+		return;
+	if (ap->port_no != 0)
 		return;
-	pci_write_config_dword(pdev, cfg_addr, val);
+	
+	pci_read_config_dword(pdev, reg, &val);
+	val = (val & ~0xf0) | (u32)timings[dev->dma_mode&0xf][0]<<4;
+	val = (val & ~0xf00) | (u32)timings[dev->dma_mode&0xf][1]<<8;
+	pci_write_config_dword(pdev, reg, val);
+
+}
+
+
+static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+	unsigned int cfg_addr;
+	u8  tmp;
+	u32 val, val2;
+		
+	// 180 / 181
+	if (pdev->device != 0x182) {
+		pci_read_config_byte(pdev, SIS_PMR, &tmp);
+		// no pata
+		if ((tmp & 0x30)== 0) {
+			if (ap->port_no == 0) 	
+				cfg_addr = 0xc0;
+			else
+				cfg_addr = 0xd0;
+			pci_read_config_dword(pdev, cfg_addr+sc_reg*4, &val);
+			return val;
+		}
+		else 
+			cfg_addr = 0xc0;
+	}
+	else {
+		if (ap->port_no == 0)
+			cfg_addr = 0xc0;
+		else
+			cfg_addr = 0xe0;
+	}
+	
+	pci_read_config_dword(pdev, cfg_addr+sc_reg*4, &val);
+	pci_read_config_dword(pdev, cfg_addr+sc_reg*4+0x10, &val2);
+	if (val == 0 && val2 == 0)
+		return val;
+	else 
+		return val|val2;	
+}
+
+static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+	unsigned int cfg_addr;
+	u8  tmp;
+	
+	// 180 / 181
+	if (pdev->device != 0x182) {
+		pci_read_config_byte(pdev, SIS_PMR, &tmp);
+		// no pata
+		if ((tmp & 0x30)== 0) {
+			if (ap->port_no == 0)
+				cfg_addr = 0xc0;
+			else
+				cfg_addr = 0xd0;
+			pci_write_config_dword(pdev, cfg_addr+scr*4, val);
+			return;
+		}
+		else 
+			cfg_addr = 0xc0;
+	}
+	// 182, one should not have chance to see 
+	else {
+		if (ap->port_no == 0)
+			cfg_addr = 0xc0;
+		else
+			cfg_addr = 0xe0;
+	}
+		
+	pci_write_config_dword(pdev, cfg_addr+scr*4, val);
+	pci_write_config_dword(pdev, cfg_addr+scr*4+0x10, val);
 }
 
 static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
 {
+	u32 result, result2;
+	u8  tmp;	
+	
 	if (sc_reg > SCR_CONTROL)
 		return 0xffffffffU;
 
-	if (ap->flags & SIS_FLAG_CFGSCR)
+	if (ap->flags & SIS_FLAG_CFGSCR) {
 		return sis_scr_cfg_read(ap, sc_reg);
-	return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+	}
+	else {
+		// 180 / 181
+		if (to_pci_dev(ap->host_set->dev)->device != 0x182) {
+			pci_read_config_byte(to_pci_dev(ap->host_set->dev), SIS_PMR, &tmp);
+			// no pata
+			if ((tmp & 0x30)== 0) 
+				return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+			// combined mode
+			else {
+				result = inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+				result2 = inl(ap->ioaddr.scr_addr+0x10 + (sc_reg * 4));
+				if (result == 0 && result2 == 0)
+					return result;
+				else 
+					return result|result2;
+			}
+		}
+		// 182		
+		else {
+			result = inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+			result2 = inl(ap->ioaddr.scr_addr+0x10 + (sc_reg * 4));
+			if (result == 0 && result2 == 0)
+				return result;
+			else 
+				return result|result2;
+		}
+	}
 }
 
 static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
 {
+	u8  tmp;
 	if (sc_reg > SCR_CONTROL)
 		return;
 
 	if (ap->flags & SIS_FLAG_CFGSCR)
 		sis_scr_cfg_write(ap, sc_reg, val);
+
+	else {
+		// 180 / 181	
+		if (to_pci_dev(ap->host_set->dev)->device != 0x182) {
+			pci_read_config_byte(to_pci_dev(ap->host_set->dev), SIS_PMR, &tmp);
+			// no pata
+			if ((tmp & 0x30)== 0) {
+				outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+			}
+			// combined mode
+			else {
+				outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+				outl(val, ap->ioaddr.scr_addr + 0x10 + (sc_reg * 4));			
+			}
+		}
+		// 182
+		else {
+			outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+			outl(val, ap->ioaddr.scr_addr + 0x10 + (sc_reg * 4));
+		}
+	}
+}
+
+/**
+	flag = 1, enable PCI int
+	flag = 0, disable PCI int
+*/
+void sis_set_int(struct ata_port *ap, int flag)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+	u32  tmp;
+	
+	pci_read_config_dword(pdev, PCI_COMMAND, &tmp);	
+	if (flag)
+		tmp &= ~PCI_COMMAND_INTX_DISABLE;
 	else
-		outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+		tmp |= PCI_COMMAND_INTX_DISABLE;
+	
+	pci_write_config_dword(pdev, PCI_COMMAND, tmp);	
+}
+
+unsigned int sis_busy_sleep (struct ata_port *ap,
+				    unsigned long tmout_pat,
+			    	    unsigned long tmout)
+{
+	unsigned long timer_start, timeout;
+	u8 status;
+
+	status = ata_busy_wait(ap, ATA_BUSY, 300);
+	timer_start = jiffies;
+	timeout = timer_start + tmout_pat;
+	while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+		msleep(50);
+		status = ata_busy_wait(ap, ATA_BUSY, 3);
+	}
+
+	if (status & ATA_BUSY)
+		DPRINTK(KERN_WARNING "ata%u is slow to respond, "
+		       "please be patient\n", ap->id);
+
+	timeout = timer_start + tmout;
+	while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+		msleep(50);
+		status = ata_chk_status(ap);
+	}
+
+	if (status & ATA_BUSY) {
+		DPRINTK(KERN_ERR "ata%u failed to respond (%lu secs)\n",
+		       ap->id, tmout / HZ);
+		return 1;
+	}
+
+	return 0;
+}
+
+void sis_bus_reset(struct ata_port *ap)
+{
+	struct ata_ioports *ioaddr = &ap->ioaddr;
+	struct ata_taskfile tf;
+	struct ata_device *dev;
+	u8 status;
+	int i;
+	
+	sis_set_int (ap, 0);
+	
+	for ( i = 0; i < 2; i++) {
+		dev = &ap->device[i];
+		dev->class = ATA_DEV_NONE;		
+		// clear signature register
+		outb(0, ioaddr->lbam_addr);
+		outb(0, ioaddr->lbah_addr);
+		// select the device		
+		ap->ops->dev_select(ap, i);
+		// issue device reset command
+		outb (ATA_DEV_RESET, ioaddr->command_addr);
+		// wait....
+		msleep(500);
+		// read it back
+		memset(&tf, 0, sizeof(tf));
+		ap->ops->tf_read(ap, &tf);
+		if (((tf.lbam == 0x14) && (tf.lbah == 0xeb))) {
+			DPRINTK("found ATAPI device by sig\n");
+			dev->class = ATA_DEV_ATAPI;
+			continue;
+		}
+		else {
+			status = ata_check_status(ap);
+			if ((status & 0xf0) == 0x50) {
+				DPRINTK("found ATA device by sig\n");
+				dev->class = ATA_DEV_ATA;
+			}
+			else {
+				DPRINTK("unknown device\n");
+				dev->class = ATA_DEV_UNKNOWN;
+			}
+		}
+	}
+	sis_set_int (ap, 1);	
 }
 
+
+void sis_sata_reset(struct ata_port *ap)
+{
+	unsigned long timeout = jiffies + (HZ * 5);
+	u32 sstatus;
+		
+	scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */
+	msleep(50);
+	scr_write(ap, SCR_CONTROL, 0x300);
+	msleep(500);
+	scr_write(ap, SCR_ERROR, 0xffffffff);
+	/* wait for phy to become ready, if necessary */
+	do {
+		msleep(100);
+		sstatus = scr_read(ap, SCR_STATUS);
+		if ((sstatus & 0xf) != 1)
+			break;
+	} while (time_before(jiffies, timeout));
+
+	if (sata_dev_present(ap))
+		ata_port_probe(ap);
+	else {
+		sstatus = scr_read(ap, SCR_STATUS);
+		DPRINTK(KERN_INFO "ata%u: no device found (phy stat %08x)\n", ap->id, sstatus);
+		ata_port_disable(ap);
+	}
+	ap->cbl = ATA_CBL_SATA;	
+}
+
+static void sis_port_reset(struct ata_port *ap)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+	u8  tmp;
+	int i;
+	
+	/* Reset routine for 180 | 181 need specail care...*/
+	if (pdev->device != 0x182) {
+		pci_read_config_byte(pdev, SIS_PMR, &tmp);
+		/* combined mode */		
+		if ((tmp & 0x30)!= 0) {
+			if (ap->port_no == 0) {
+				ata_port_probe(ap);
+				// detect cable type
+				pci_read_config_byte(pdev, SIS_CHANNEL_CTRL, &tmp);
+				if (tmp & 0x1) {
+					DPRINTK ("PATA use 40pin cable\n");
+					ap->cbl = ATA_CBL_PATA40;
+					ap->udma_mask &= ATA_UDMA_MASK_40C;
+				}
+				else {
+					DPRINTK ("PATA use 80pin cable\n");
+					ap->cbl = ATA_CBL_PATA80;
+				}
+			}
+			/* pure sata mode, one device one channel */
+			else 
+				sis_sata_reset(ap);
+		}
+		// pure sata mode
+		else
+			sis_sata_reset(ap);
+	}
+	/* for 182 section */
+	else
+		sis_sata_reset(ap);
+	
+	if (ap->flags & ATA_FLAG_PORT_DISABLED)
+		return;
+	//  give device chances to be ready
+	for ( i = 0; i<10; i++)
+	{
+		tmp = inb(ap->ioaddr.status_addr);
+		if (tmp == 0x80)
+			msleep(50);
+	}
+
+	sis_bus_reset(ap);
+}
+
+
 /* move to PCI layer, integrate w/ MSI stuff */
 static void pci_enable_intx(struct pci_dev *pdev)
 {
@@ -204,6 +641,7 @@
 	int rc;
 	u32 genctl;
 	struct ata_port_info *ppi;
+	u8 tmp;
 	int pci_dev_busy = 0;
 
 	rc = pci_enable_device(pdev);
@@ -229,7 +667,7 @@
 		rc = -ENOMEM;
 		goto err_out_regions;
 	}
-
+	
 	/* check and see if the SCRs are in IO space or PCI cfg space */
 	pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
 	if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
@@ -247,12 +685,33 @@
 	}
 
 	if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR)) {
-		probe_ent->port[0].scr_addr =
-			pci_resource_start(pdev, SIS_SCR_PCI_BAR);
-		probe_ent->port[1].scr_addr =
-			pci_resource_start(pdev, SIS_SCR_PCI_BAR) + 64;
+		if (ent->driver_data == sis_180) {
+			pci_read_config_byte(pdev, SIS_PMR, &tmp);
+			if ((tmp & 0x30)== 0) {
+				DPRINTK ("SiS-180/181 pure sata mode detected\n");
+				probe_ent->port[0].scr_addr = pci_resource_start(pdev, SIS_SCR_PCI_BAR);
+				probe_ent->port[1].scr_addr = pci_resource_start(pdev, SIS_SCR_PCI_BAR) + 64;
+			}
+			else {
+				DPRINTK ("SiS-180/181 combined mode detected!\n");
+				probe_ent->port[1].scr_addr = pci_resource_start(pdev, SIS_SCR_PCI_BAR);
+			}
+		}
+		if (ent->driver_data == sis_182) {
+			probe_ent->port[0].scr_addr = pci_resource_start(pdev, SIS_SCR_PCI_BAR);
+			probe_ent->port[1].scr_addr = pci_resource_start(pdev, SIS_SCR_PCI_BAR) + 0x20;
+		}
 	}
-
+	else {
+		if (ent->driver_data == sis_180) {
+			pci_read_config_byte(pdev, SIS_PMR, &tmp);
+			if ((tmp & 0x30)== 0)
+				DPRINTK ("SiS-180/181 pure sata mode detected\n");
+			else
+				DPRINTK ("combined mode detected!\n");			
+		}		
+	}
+	
 	pci_set_master(pdev);
 	pci_enable_intx(pdev);
 
@@ -272,6 +731,7 @@
 
 }
 
+
 static int __init sis_init(void)
 {
 	return pci_module_init(&sis_pci_driver);
@@ -284,4 +744,3 @@
 
 module_init(sis_init);
 module_exit(sis_exit);
-
