Skip to contentSkip to conversation

ATA : vortex86 : fix vortex86dx/sx hardware CRC bug.

PATCH In review Paul Schilling 2 participants 2 messages Oct 22, 2011 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): Vortex86_PATA

#1 lore raw

PATCH 1/14 ATA : vortex86 : fix vortex86dx/sx hardware CRC bug.

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

---
 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(-)
drivers/ata/pata_it821x.c +138 -126
index 62c5d00..eaf9c1e 100644
@@ -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 <[email protected]>
  *			  (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");
 
drivers/ata/pata_rdc.c +27 -8
index 4d318f8..85b1e11 100644
@@ -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 */
 };
 
drivers/ide/it821x.c +7 -2
index 2e3169f..82c6bc7 100644
@@ -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, },
 };
 
include/linux/pci_ids.h +2 -0
index ae96bbe..237da92 100644
@@ -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
 
Signature · 1 line
1.7.6.4
#2 lore raw
Quoted 4 lines · Paul Schilling

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

I'm sorry, this is not acceptable.

You missed in hundreds of lines of useless reformatting in amongst the fixes.

Please separate out logical changes - thus, any whitespace/reformatting must be in a separate patch from your fixes.