[PATCH 01/14] ATA : vortex86 : fix vortex86dx/sx hardware CRC bug.

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

 



This fixes a DMA issue related to a CRC bug on
the RDC pata peripherial found on the vortex86sx and vortex86dx.

Signed-off-by: Paul Schilling <paul.s.schilling@xxxxxxxxx>
---
 drivers/ata/pata_it821x.c |  264 +++++++++++++++++++++++---------------------
 drivers/ata/pata_rdc.c    |   35 +++++--
 drivers/ide/it821x.c      |    9 ++-
 include/linux/pci_ids.h   |    2 +
 4 files changed, 174 insertions(+), 136 deletions(-)

diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 62c5d00..eaf9c1e 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -1,5 +1,5 @@
 /*
- * pata_it821x.c 	- IT821x PATA for new ATA layer
+ * pata_it821x.c	- IT821x PATA for new ATA layer
  *			  (C) 2005 Red Hat Inc
  *			  Alan Cox <alan@xxxxxxxxxxxxxxxxxxx>
  *			  (C) 2007 Bartlomiej Zolnierkiewicz
@@ -16,7 +16,7 @@
  *  Based in part on the ITE vendor provided SCSI driver.
  *
  *  Documentation available from IT8212F_V04.pdf
- * 	http://www.ite.com.tw/EN/products_more.aspx?CategoryID=3&ID=5,91
+ *	http://www.ite.com.tw/EN/products_more.aspx?CategoryID=3&ID=5,91
  *  Some other documents are NDA.
  *
  *  The ITE8212 isn't exactly a standard IDE controller. It has two
@@ -79,22 +79,20 @@
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
-
 #define DRV_NAME "pata_it821x"
 #define DRV_VERSION "0.4.2"
 
-struct it821x_dev
-{
-	unsigned int smart:1,		/* Are we in smart raid mode */
-		timing10:1;		/* Rev 0x10 */
-	u8	clock_mode;		/* 0, ATA_50 or ATA_66 */
-	u8	want[2][2];		/* Mode/Pri log for master slave */
+struct it821x_dev {
+	unsigned int smart:1,	/* Are we in smart raid mode */
+	 timing10:1;		/* Rev 0x10 */
+	u8 clock_mode;		/* 0, ATA_50 or ATA_66 */
+	u8 want[2][2];		/* Mode/Pri log for master slave */
 	/* We need these for switching the clock when DMA goes on/off
 	   The high byte is the 66Mhz timing */
-	u16	pio[2];			/* Cached PIO values */
-	u16	mwdma[2];		/* Cached MWDMA values */
-	u16	udma[2];		/* Cached UDMA values (per drive) */
-	u16	last_device;		/* Master or slave loaded ? */
+	u16 pio[2];		/* Cached PIO values */
+	u16 mwdma[2];		/* Cached MWDMA values */
+	u16 udma[2];		/* Cached UDMA values (per drive) */
+	u16 last_device;	/* Master or slave loaded ? */
 };
 
 #define ATA_66		0
@@ -124,7 +122,8 @@ static int it8212_noraid;
  *	the DMA start/stop sequence as with the old driver.
  */
 
-static void it821x_program(struct ata_port *ap, struct ata_device *adev, u16 timing)
+static void it821x_program(struct ata_port *ap, struct ata_device *adev,
+			   u16 timing)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	struct it821x_dev *itdev = ap->private_data;
@@ -139,7 +138,6 @@ static void it821x_program(struct ata_port *ap, struct ata_device *adev, u16 tim
 	pci_write_config_byte(pdev, 0x54 + 4 * channel, conf);
 }
 
-
 /**
  *	it821x_program_udma	-	program the UDMA registers
  *	@ap: ATA port
@@ -152,7 +150,8 @@ static void it821x_program(struct ata_port *ap, struct ata_device *adev, u16 tim
  *	here and partly in start_dma.
  */
 
-static void it821x_program_udma(struct ata_port *ap, struct ata_device *adev, u16 timing)
+static void it821x_program_udma(struct ata_port *ap, struct ata_device *adev,
+				u16 timing)
 {
 	struct it821x_dev *itdev = ap->private_data;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
@@ -227,16 +226,16 @@ static void it821x_clock_strategy(struct ata_port *ap, struct ata_device *adev)
 	pci_write_config_byte(pdev, 0x50, v);
 
 	/*
-	 *	Reprogram the UDMA/PIO of the pair drive for the switch
-	 *	MWDMA will be dealt with by the dma switcher
+	 *      Reprogram the UDMA/PIO of the pair drive for the switch
+	 *      MWDMA will be dealt with by the dma switcher
 	 */
-	if (pair && itdev->udma[1-unit] != UDMA_OFF) {
-		it821x_program_udma(ap, pair, itdev->udma[1-unit]);
-		it821x_program(ap, pair, itdev->pio[1-unit]);
+	if (pair && itdev->udma[1 - unit] != UDMA_OFF) {
+		it821x_program_udma(ap, pair, itdev->udma[1 - unit]);
+		it821x_program(ap, pair, itdev->pio[1 - unit]);
 	}
 	/*
-	 *	Reprogram the UDMA/PIO of our drive for the switch.
-	 *	MWDMA will be dealt with by the dma switcher
+	 *      Reprogram the UDMA/PIO of our drive for the switch.
+	 *      MWDMA will be dealt with by the dma switcher
 	 */
 	if (itdev->udma[unit] != UDMA_OFF) {
 		it821x_program_udma(ap, adev, itdev->udma[unit]);
@@ -253,11 +252,13 @@ static void it821x_clock_strategy(struct ata_port *ap, struct ata_device *adev)
  *	shared by PIO and MWDMA and for both channels.
  */
 
-static void it821x_passthru_set_piomode(struct ata_port *ap, struct ata_device *adev)
+static void it821x_passthru_set_piomode(struct ata_port *ap,
+					struct ata_device *adev)
 {
 	/* Spec says 89 ref driver uses 88 */
-	static const u16 pio[]	= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };
-	static const u8 pio_want[]    = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY };
+	static const u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };
+	static const u8 pio_want[] = {
+			ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY };
 
 	struct it821x_dev *itdev = ap->private_data;
 	int unit = adev->devno;
@@ -283,12 +284,17 @@ static void it821x_passthru_set_piomode(struct ata_port *ap, struct ata_device *
  *	we switch devices and mode.
  */
 
-static void it821x_passthru_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+static void it821x_passthru_set_dmamode(struct ata_port *ap,
+					struct ata_device *adev)
 {
-	static const u16 dma[]	= 	{ 0x8866, 0x3222, 0x3121 };
-	static const u8 mwdma_want[] =  { ATA_ANY, ATA_66, ATA_ANY };
-	static const u16 udma[]	= 	{ 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 };
-	static const u8 udma_want[] =   { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 };
+	static const u16 dma[] = { 0x8866, 0x3222, 0x3121 };
+	static const u8 mwdma_want[] = { ATA_ANY, ATA_66, ATA_ANY };
+	static const u16 udma[] = {
+			0x4433, 0x4231, 0x3121,
+			0x2121, 0x1111, 0x2211, 0x1111 };
+	static const u8 udma_want[] = {
+			ATA_ANY, ATA_50, ATA_ANY,
+			ATA_66, ATA_66, ATA_50, ATA_66 };
 
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	struct it821x_dev *itdev = ap->private_data;
@@ -309,9 +315,9 @@ static void it821x_passthru_set_dmamode(struct ata_port *ap, struct ata_device *
 		/* UDMA on. Again revision 0x10 must do the pair */
 		pci_read_config_byte(pdev, 0x50, &conf);
 		if (itdev->timing10)
-			conf &= channel ? 0x9F: 0xE7;
+			conf &= channel ? 0x9F : 0xE7;
 		else
-			conf &= ~ (1 << (3 + 2 * channel + unit));
+			conf &= ~(1 << (3 + 2 * channel + unit));
 		pci_write_config_byte(pdev, 0x50, conf);
 		it821x_clock_strategy(ap, adev);
 		it821x_program_udma(ap, adev, itdev->udma[unit]);
@@ -326,7 +332,7 @@ static void it821x_passthru_set_dmamode(struct ata_port *ap, struct ata_device *
 		/* UDMA bits off - Revision 0x10 do them in pairs */
 		pci_read_config_byte(pdev, 0x50, &conf);
 		if (itdev->timing10)
-			conf |= channel ? 0x60: 0x18;
+			conf |= channel ? 0x60 : 0x18;
 		else
 			conf |= 1 << (3 + 2 * channel + unit);
 		pci_write_config_byte(pdev, 0x50, conf);
@@ -378,7 +384,6 @@ static void it821x_passthru_bmdma_stop(struct ata_queued_cmd *qc)
 		it821x_program(ap, adev, itdev->pio[unit]);
 }
 
-
 /**
  *	it821x_passthru_dev_select	-	Select master/slave
  *	@ap: ATA port
@@ -387,8 +392,7 @@ static void it821x_passthru_bmdma_stop(struct ata_queued_cmd *qc)
  *	Device selection hook. If necessary perform clock switching
  */
 
-static void it821x_passthru_dev_select(struct ata_port *ap,
-				       unsigned int device)
+static void it821x_passthru_dev_select(struct ata_port *ap, unsigned int device)
 {
 	struct it821x_dev *itdev = ap->private_data;
 	if (itdev && device != itdev->last_device) {
@@ -410,29 +414,29 @@ static void it821x_passthru_dev_select(struct ata_port *ap,
 
 static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc)
 {
-	switch(qc->tf.command)
-	{
+	switch (qc->tf.command) {
 		/* Commands the firmware supports */
-		case ATA_CMD_READ:
-		case ATA_CMD_READ_EXT:
-		case ATA_CMD_WRITE:
-		case ATA_CMD_WRITE_EXT:
-		case ATA_CMD_PIO_READ:
-		case ATA_CMD_PIO_READ_EXT:
-		case ATA_CMD_PIO_WRITE:
-		case ATA_CMD_PIO_WRITE_EXT:
-		case ATA_CMD_READ_MULTI:
-		case ATA_CMD_READ_MULTI_EXT:
-		case ATA_CMD_WRITE_MULTI:
-		case ATA_CMD_WRITE_MULTI_EXT:
-		case ATA_CMD_ID_ATA:
-		case ATA_CMD_INIT_DEV_PARAMS:
-		case 0xFC:	/* Internal 'report rebuild state' */
+	case ATA_CMD_READ:
+	case ATA_CMD_READ_EXT:
+	case ATA_CMD_WRITE:
+	case ATA_CMD_WRITE_EXT:
+	case ATA_CMD_PIO_READ:
+	case ATA_CMD_PIO_READ_EXT:
+	case ATA_CMD_PIO_WRITE:
+	case ATA_CMD_PIO_WRITE_EXT:
+	case ATA_CMD_READ_MULTI:
+	case ATA_CMD_READ_MULTI_EXT:
+	case ATA_CMD_WRITE_MULTI:
+	case ATA_CMD_WRITE_MULTI_EXT:
+	case ATA_CMD_ID_ATA:
+	case ATA_CMD_INIT_DEV_PARAMS:
+	case 0xFC:		/* Internal 'report rebuild state' */
 		/* Arguably should just no-op this one */
-		case ATA_CMD_SET_FEATURES:
-			return ata_bmdma_qc_issue(qc);
+	case ATA_CMD_SET_FEATURES:
+		return ata_bmdma_qc_issue(qc);
 	}
-	printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command);
+	printk(KERN_DEBUG "it821x: can't process command 0x%02X\n",
+	       qc->tf.command);
 	return AC_ERR_DEV;
 }
 
@@ -462,7 +466,8 @@ static unsigned int it821x_passthru_qc_issue(struct ata_queued_cmd *qc)
  *	and respect them.
  */
 
-static int it821x_smart_set_mode(struct ata_link *link, struct ata_device **unused)
+static int it821x_smart_set_mode(struct ata_link *link,
+				 struct ata_device **unused)
 {
 	struct ata_device *dev;
 
@@ -509,8 +514,7 @@ static void it821x_dev_config(struct ata_device *adev)
 	if (strstr(model_num, "Integrated Technology Express")) {
 		/* RAID mode */
 		ata_dev_info(adev, "%sRAID%d volume",
-			     adev->id[147] ? "Bootable " : "",
-			     adev->id[129]);
+			     adev->id[147] ? "Bootable " : "", adev->id[129]);
 		if (adev->id[129] != 1)
 			pr_cont("(%dK stripe)", adev->id[146]);
 		pr_cont("\n");
@@ -535,7 +539,7 @@ static void it821x_dev_config(struct ata_device *adev)
  */
 
 static unsigned int it821x_read_id(struct ata_device *adev,
-					struct ata_taskfile *tf, u16 *id)
+				   struct ata_taskfile *tf, u16 * id)
 {
 	unsigned int err_mask;
 	unsigned char model_num[ATA_ID_PROD_LEN + 1];
@@ -616,7 +620,7 @@ static void it821x_display_disk(int n, u8 *buf)
 	if (buf[52] > 4)	/* No Disk */
 		return;
 
-	ata_id_c_string((u16 *)buf, id, 0, 41);
+	ata_id_c_string((u16 *) buf, id, 0, 41);
 
 	if (buf[51]) {
 		mode = ffs(buf[51]);
@@ -635,10 +639,10 @@ static void it821x_display_disk(int n, u8 *buf)
 		strcpy(mbuf, "PIO");
 	if (buf[52] == 4)
 		printk(KERN_INFO "%d: %-6s %-8s          %s %s\n",
-				n, mbuf, types[buf[52]], id, cbl);
+		       n, mbuf, types[buf[52]], id, cbl);
 	else
 		printk(KERN_INFO "%d: %-6s %-8s Volume: %1d %s %s\n",
-				n, mbuf, types[buf[52]], buf[53], id, cbl);
+		       n, mbuf, types[buf[52]], buf[53], id, cbl);
 	if (buf[125] < 100)
 		printk(KERN_INFO "%d: Rebuilding: %d%%\n", n, buf[125]);
 }
@@ -673,7 +677,7 @@ static u8 *it821x_firmware_command(struct ata_port *ap, u8 cmd, int len)
 	udelay(1);
 	/* This should be almost immediate but a little paranoia goes a long
 	   way. */
-	while(n++ < 10) {
+	while (n++ < 10) {
 		status = ioread8(ap->ioaddr.status_addr);
 		if (status & ATA_ERR) {
 			kfree(buf);
@@ -681,8 +685,8 @@ static u8 *it821x_firmware_command(struct ata_port *ap, u8 cmd, int len)
 			return NULL;
 		}
 		if (status & ATA_DRQ) {
-			ioread16_rep(ap->ioaddr.data_addr, buf, len/2);
-			return (u8 *)buf;
+			ioread16_rep(ap->ioaddr.data_addr, buf, len / 2);
+			return (u8 *) buf;
 		}
 		mdelay(1);
 	}
@@ -711,18 +715,13 @@ static void it821x_probe_firmware(struct ata_port *ap)
 
 	if (buf != NULL) {
 		printk(KERN_INFO "pata_it821x: Firmware %02X/%02X/%02X%02X\n",
-				buf[505],
-				buf[506],
-				buf[507],
-				buf[508]);
+		       buf[505], buf[506], buf[507], buf[508]);
 		for (i = 0; i < 4; i++)
- 			it821x_display_disk(i, buf + 128 * i);
+			it821x_display_disk(i, buf + 128 * i);
 		kfree(buf);
 	}
 }
 
-
-
 /**
  *	it821x_port_start	-	port setup
  *	@ap: ATA port being set up
@@ -772,7 +771,8 @@ static int it821x_port_start(struct ata_port *ap)
 		itdev->timing10 = 1;
 		/* Need to disable ATAPI DMA for this case */
 		if (!itdev->smart)
-			printk(KERN_WARNING DRV_NAME": Revision 0x10, workarounds activated.\n");
+			printk(KERN_WARNING DRV_NAME
+			       ": Revision 0x10, workarounds activated.\n");
 	}
 
 	return 0;
@@ -802,57 +802,57 @@ static struct scsi_host_template it821x_sht = {
 };
 
 static struct ata_port_operations it821x_smart_port_ops = {
-	.inherits	= &ata_bmdma_port_ops,
+	.inherits = &ata_bmdma_port_ops,
 
-	.check_atapi_dma= it821x_check_atapi_dma,
-	.qc_issue	= it821x_smart_qc_issue,
+	.check_atapi_dma = it821x_check_atapi_dma,
+	.qc_issue = it821x_smart_qc_issue,
 
-	.cable_detect	= ata_cable_80wire,
-	.set_mode	= it821x_smart_set_mode,
-	.dev_config	= it821x_dev_config,
-	.read_id	= it821x_read_id,
+	.cable_detect = ata_cable_80wire,
+	.set_mode = it821x_smart_set_mode,
+	.dev_config = it821x_dev_config,
+	.read_id = it821x_read_id,
 
-	.port_start	= it821x_port_start,
+	.port_start = it821x_port_start,
 };
 
 static struct ata_port_operations it821x_passthru_port_ops = {
-	.inherits	= &ata_bmdma_port_ops,
+	.inherits = &ata_bmdma_port_ops,
 
-	.check_atapi_dma= it821x_check_atapi_dma,
-	.sff_dev_select	= it821x_passthru_dev_select,
-	.bmdma_start 	= it821x_passthru_bmdma_start,
-	.bmdma_stop	= it821x_passthru_bmdma_stop,
-	.qc_issue	= it821x_passthru_qc_issue,
+	.check_atapi_dma = it821x_check_atapi_dma,
+	.sff_dev_select = it821x_passthru_dev_select,
+	.bmdma_start = it821x_passthru_bmdma_start,
+	.bmdma_stop = it821x_passthru_bmdma_stop,
+	.qc_issue = it821x_passthru_qc_issue,
 
-	.cable_detect	= ata_cable_unknown,
-	.set_piomode	= it821x_passthru_set_piomode,
-	.set_dmamode	= it821x_passthru_set_dmamode,
+	.cable_detect = ata_cable_unknown,
+	.set_piomode = it821x_passthru_set_piomode,
+	.set_dmamode = it821x_passthru_set_dmamode,
 
-	.port_start	= it821x_port_start,
+	.port_start = it821x_port_start,
 };
 
 static struct ata_port_operations it821x_rdc_port_ops = {
-	.inherits	= &ata_bmdma_port_ops,
+	.inherits = &ata_bmdma_port_ops,
 
-	.check_atapi_dma= it821x_check_atapi_dma,
-	.sff_dev_select	= it821x_passthru_dev_select,
-	.bmdma_start 	= it821x_passthru_bmdma_start,
-	.bmdma_stop	= it821x_passthru_bmdma_stop,
-	.qc_issue	= it821x_passthru_qc_issue,
+	.check_atapi_dma = it821x_check_atapi_dma,
+	.sff_dev_select = it821x_passthru_dev_select,
+	.bmdma_start = it821x_passthru_bmdma_start,
+	.bmdma_stop = it821x_passthru_bmdma_stop,
+	.qc_issue = it821x_passthru_qc_issue,
 
-	.cable_detect	= it821x_rdc_cable,
-	.set_piomode	= it821x_passthru_set_piomode,
-	.set_dmamode	= it821x_passthru_set_dmamode,
+	.cable_detect = it821x_rdc_cable,
+	.set_piomode = it821x_passthru_set_piomode,
+	.set_dmamode = it821x_passthru_set_dmamode,
 
-	.port_start	= it821x_port_start,
+	.port_start = it821x_port_start,
 };
 
 static void it821x_disable_raid(struct pci_dev *pdev)
 {
 	/* Neither the RDC nor the IT8211 */
 	if (pdev->vendor != PCI_VENDOR_ID_ITE ||
-			pdev->device != PCI_DEVICE_ID_ITE_8212)
-			return;
+	    pdev->device != PCI_DEVICE_ID_ITE_8212)
+		return;
 
 	/* Reset local CPU, and set BIOS not ready */
 	pci_write_config_byte(pdev, 0x5E, 0x01);
@@ -864,12 +864,11 @@ static void it821x_disable_raid(struct pci_dev *pdev)
 			      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 	pci_write_config_word(pdev, 0x40, 0xA0F3);
 
-	pci_write_config_dword(pdev,0x4C, 0x02040204);
+	pci_write_config_dword(pdev, 0x4C, 0x02040204);
 	pci_write_config_byte(pdev, 0x42, 0x36);
 	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
 }
 
-
 static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	u8 conf;
@@ -898,7 +897,16 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	static const struct ata_port_info info_rdc_11 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
 		.pio_mask = ATA_PIO4,
-		.mwdma_mask = ATA_MWDMA2,
+		.mwdma_mask = 0,
+		.udma_mask = 0,
+		/* No UDMA */
+		.port_ops = &it821x_rdc_port_ops
+	};
+	static const struct ata_port_info info_rdc_01 = {
+		.flags = ATA_FLAG_SLAVE_POSS,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = 0,
+		.udma_mask = 0,
 		/* No UDMA */
 		.port_ops = &it821x_rdc_port_ops
 	};
@@ -912,11 +920,16 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		return rc;
 
 	if (pdev->vendor == PCI_VENDOR_ID_RDC) {
-		/* Deal with Vortex86SX */
-		if (pdev->revision == 0x11)
+		if (((pdev->revision == 0x11) || (pdev->revision == 0x13)) &&
+		    (pdev->device == PCI_DEVICE_ID_RDC_D1010)) {
+			/* Deal with Vortex86SX */
 			ppi[0] = &info_rdc_11;
-		else
+			printk(KERN_INFO DRV_NAME
+			       ": Detected Vortex86SX/DX Bug.\n");
+			printk(KERN_INFO DRV_NAME ": Disabling UDMA.\n");
+		} else {
 			ppi[0] = &info_rdc;
+		}
 	} else {
 		/* Force the card into bypass mode if so requested */
 		if (it8212_noraid) {
@@ -926,8 +939,8 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		pci_read_config_byte(pdev, 0x50, &conf);
 		conf &= 1;
 
-		printk(KERN_INFO DRV_NAME": controller in %s mode.\n",
-								mode[conf]);
+		printk(KERN_INFO DRV_NAME ": controller in %s mode.\n",
+		       mode[conf]);
 		if (conf == 0)
 			ppi[0] = &info_passthru;
 		else
@@ -954,21 +967,20 @@ static int it821x_reinit_one(struct pci_dev *pdev)
 #endif
 
 static const struct pci_device_id it821x[] = {
-	{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
-	{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), },
-	{ PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010), },
-
-	{ },
+	{PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211),},
+	{PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212),},
+	{PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010),},
+	{},
 };
 
 static struct pci_driver it821x_pci_driver = {
-	.name 		= DRV_NAME,
-	.id_table	= it821x,
-	.probe 		= it821x_init_one,
-	.remove		= ata_pci_remove_one,
+	.name = DRV_NAME,
+	.id_table = it821x,
+	.probe = it821x_init_one,
+	.remove = ata_pci_remove_one,
 #ifdef CONFIG_PM
-	.suspend	= ata_pci_device_suspend,
-	.resume		= it821x_reinit_one,
+	.suspend = ata_pci_device_suspend,
+	.resume = it821x_reinit_one,
 #endif
 };
 
@@ -983,12 +995,12 @@ static void __exit it821x_exit(void)
 }
 
 MODULE_AUTHOR("Alan Cox");
-MODULE_DESCRIPTION("low-level driver for the IT8211/IT8212 IDE RAID controller");
+MODULE_DESCRIPTION
+("low-level driver for the IT8211/IT8212 IDE RAID controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, it821x);
 MODULE_VERSION(DRV_VERSION);
 
-
 module_param_named(noraid, it8212_noraid, int, S_IRUGO);
 MODULE_PARM_DESC(noraid, "Force card into bypass mode");
 
diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c
index 4d318f8..85b1e11 100644
--- a/drivers/ata/pata_rdc.c
+++ b/drivers/ata/pata_rdc.c
@@ -258,7 +258,7 @@ static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 			/* Load the matching timing */
 			slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
 			pci_write_config_byte(dev, 0x44, slave_data);
-		} else { 	/* Master */
+		} else {	/* Master */
 			master_data &= 0xCCF4;	/* Mask out IORDY|TIME1|DMAONLY
 						   and master timing bits */
 			master_data |= control;
@@ -290,6 +290,16 @@ static struct ata_port_info rdc_port_info = {
 	.port_ops	= &rdc_pata_ops,
 };
 
+static struct ata_port_info vortex_port_info = {
+	.flags = ATA_FLAG_SLAVE_POSS,
+	.pio_mask = ATA_PIO4,
+	.mwdma_mask = 0,
+	.udma_mask = 0,
+	/* No UDMA */
+	.port_ops	= &rdc_pata_ops,
+};
+
+
 static struct scsi_host_template rdc_sht = {
 	ATA_BMDMA_SHT(DRV_NAME),
 };
@@ -322,16 +332,25 @@ static int __devinit rdc_init_one(struct pci_dev *pdev,
 
 	ata_print_version_once(&pdev->dev, DRV_VERSION);
 
-	port_info[0] = rdc_port_info;
-	port_info[1] = rdc_port_info;
-
-	port_flags = port_info[0].flags;
-
 	/* enable device and prepare host */
 	rc = pcim_enable_device(pdev);
 	if (rc)
 		return rc;
 
+	if ((pdev->revision == 0x01) &&
+			(pdev->device ==  PCI_DEVICE_ID_RDC_D1011)) {
+		/* Deal with Vortex86DX */
+		port_info[0] = vortex_port_info;
+		port_info[1] = vortex_port_info;
+		printk(KERN_INFO DRV_NAME ": Detected Vortex86DX Bug.\n");
+		printk(KERN_INFO DRV_NAME ": Disabling UDMA.\n");
+	} else {
+		port_info[0] = rdc_port_info;
+		port_info[1] = rdc_port_info;
+	}
+
+	port_flags = port_info[0].flags;
+
 	hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
 	if (!hpriv)
 		return -ENOMEM;
@@ -365,8 +384,8 @@ static void rdc_remove_one(struct pci_dev *pdev)
 }
 
 static const struct pci_device_id rdc_pci_tbl[] = {
-	{ PCI_DEVICE(0x17F3, 0x1011), },
-	{ PCI_DEVICE(0x17F3, 0x1012), },
+	{ PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1011), },
+	{ PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1012), },
 	{ }	/* terminate list */
 };
 
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index 2e3169f..82c6bc7 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -581,10 +581,14 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
 	hwif->ultra_mask = ATA_UDMA6;
 	hwif->mwdma_mask = ATA_MWDMA2;
 
-	/* Vortex86SX quirk: prevent Ultra-DMA mode to fix BadCRC issue */
+	/* Vortex86SX and Vortex86DX quirk: prevent
+	 * Ultra-DMA mode to fix BadCRC issue when
+	 * using DMA mode */
 	if (idev->quirks & QUIRK_VORTEX86) {
-		if (dev->revision == 0x11)
+		if (((dev->revision == 0x11) || (dev->revision == 0x13))
+				|| (dev->revision == 0x01)) {
 			hwif->ultra_mask = 0;
+		}
 	}
 }
 
@@ -680,6 +684,7 @@ static const struct pci_device_id it821x_pci_tbl[] = {
 	{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), 0 },
 	{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), 0 },
 	{ PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010), QUIRK_VORTEX86 },
+	{ PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1011), QUIRK_VORTEX86 },
 	{ 0, },
 };
 
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ae96bbe..237da92 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2259,6 +2259,8 @@
 #define PCI_DEVICE_ID_RDC_R6060		0x6060
 #define PCI_DEVICE_ID_RDC_R6061		0x6061
 #define PCI_DEVICE_ID_RDC_D1010		0x1010
+#define PCI_DEVICE_ID_RDC_D1011		0x1011
+#define PCI_DEVICE_ID_RDC_D1012		0x1012
 
 #define PCI_VENDOR_ID_LENOVO		0x17aa
 
-- 
1.7.6.4

--
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