Patch: ATI Xilleon port 10/11 Xilleon IDE controller support

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

 



This is the tenth part of my Xilleon port.

I am sending the full set of patches to linux-mips@xxxxxxxxxxxxxx
which is archived at: http://www.linux-mips.org/archives/

Only the patches that touch generic parts of the kernel are coming
here.

This patch adds the Xilleon's IDE driver.

Patch against 2.6.14-rc2 from linux-mips.org

Signed-off-by: David Daney <ddaney@xxxxxxxxxx>

Xilleon IDE controller support.

---
commit 2a66e82b3d2b02aca88cc2f60286fba0c114139d
tree af6a21de182519250b49d5b127342b969c022174
parent 162fee1af111103bb6e6275c2e51a550ff393cbc
author David Daney <daney@xxxxxxxxxxxxxxxxxx> Tue, 04 Oct 2005 13:59:58 -0700
committer David Daney <daney@xxxxxxxxxxxxxxxxxx> Tue, 04 Oct 2005 13:59:58 -0700

 drivers/ide/Kconfig       |    7 
 drivers/ide/pci/Makefile  |    1 
 drivers/ide/pci/xilleon.c |  637 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 645 insertions(+), 0 deletions(-)

diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -740,6 +740,13 @@ config BLK_DEV_VIA82CXXX
 	  This allows the kernel to change PIO, DMA and UDMA speeds and to
 	  configure the chip to optimum performance.
 
+config BLK_DEV_IDE_XILLEON
+	bool "Xilleon chipset support"
+	depends on ATI_XILLEON
+	help
+	  This driver provides support for the Xilleon's on chip IDE
+          controller.
+
 endif
 
 config BLK_DEV_IDE_PMAC
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_BLK_DEV_SLC90E66)		+= slc90
 obj-$(CONFIG_BLK_DEV_TRIFLEX)		+= triflex.o
 obj-$(CONFIG_BLK_DEV_TRM290)		+= trm290.o
 obj-$(CONFIG_BLK_DEV_VIA82CXXX)		+= via82cxxx.o
+obj-$(CONFIG_BLK_DEV_IDE_XILLEON)	+= xilleon.o
 
 # Must appear at the end of the block
 obj-$(CONFIG_BLK_DEV_GENERIC)          += generic.o
diff --git a/drivers/ide/pci/xilleon.c b/drivers/ide/pci/xilleon.c
new file mode 100644
--- /dev/null
+++ b/drivers/ide/pci/xilleon.c
@@ -0,0 +1,637 @@
+/*
+ * ATI Xilleon 225/226 UDMA controller driver
+ *
+ * Copyright (C) 2001, 2002 Metro Link, Inc.
+ *
+ * Port to kernel version 2.6.12 by David Daney loosely based on the 2.4.18
+ * version by Metro Link and ATI.  Also based on code in via82cxxx.c
+ *
+ *
+ * May be copied or modified under the terms of the GNU General Public License 
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+#include <asm/mach-xilleon/xilleon.h>
+#include <asm/mach-xilleon/xilleonreg_kernel.h>
+#include <asm/mach-xilleon/xilleonint.h>
+
+#include <asm/io.h>
+
+int xilleon_ide_proc;
+
+static struct pci_dev *bmide_dev;
+
+/* #define DEBUG 1 */
+
+#if defined(CONFIG_PROC_FS)
+static u8 xilleon_proc = 0;
+
+/**
+ *	xilleon_ide_get_info		-	generate xilleon /proc file 
+ *	@buffer: buffer for data
+ *	@addr: set to start of data to use
+ *	@offset: current file offset
+ *	@count: size of read
+ *
+ *	Fills in buffer with the debugging/configuration information for
+ *	the Xilleon tuning and attached drives
+ */
+
+static int xilleon_ide_get_info(char *buffer,
+				char **addr, off_t offset, int count)
+{
+	char *p = buffer;
+	u32 bibma = pci_resource_start(bmide_dev, 4);
+	struct pci_dev *dev = bmide_dev;
+	u8 c0 = 0;
+	u8 c1 = 0;
+	u8 d0 = 0;
+	u8 d1 = 0;
+	u8 udma_control;
+
+	p += sprintf(p, "\n     ATI Xilleon Chipset.\n");
+
+	pci_read_config_byte(dev, PCI_REVISION_ID, &c1);
+
+	p+= sprintf(p, "       Revision:   %#x\n", c1);
+
+        /*
+         * at that point bibma+0x2 et bibma+0xa are byte registers
+         * to investigate:
+         */
+
+	pci_read_config_byte(bmide_dev, pciideIDE_UDMA_CONTROL, &udma_control);
+	pci_read_config_byte(bmide_dev, pciideX225_IDE_DMA_MODE + 0, &d0);
+	pci_read_config_byte(bmide_dev, pciideX225_IDE_DMA_MODE + 1, &d1);
+
+
+	c0 = inb_p((unsigned short)bibma + 0x02);
+	c1 = inb_p((unsigned short)bibma + 0x0a);
+
+	p += sprintf(p, "--------------- Primary Channel ----------------\n");
+	p += sprintf(p, "                %sabled\n",
+		     (c0&0x80) ? "dis" : " en");
+
+	p += sprintf(p, "--------------- drive0 --------- drive1 --------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s\n",
+		     (c0&0x20) ? "yes" : "no ",
+		     (c0&0x40) ? "yes" : "no ");
+
+	p += sprintf(p, "UDMA enabled:   %s              %s\n",
+		     (udma_control & 0x01) ? "yes" : "no ",
+		     (udma_control & 0x02) ? "yes" : "no ");
+
+	p += sprintf(p, "Mode:           %sDMA %d          %sDMA %d\n",
+		     d0 & 0x10 ? "U" : " ", d0 & 0xf,
+		     d1 & 0x10 ? "U" : " ", d1 & 0xf);
+	
+	return p-buffer;     /* => must be less than 4k! */
+}
+
+#endif
+
+/*
+ * initialize the x225 chip
+ */
+
+static unsigned int __devinit pci_init_x225_ide (struct pci_dev *dev,
+						 const char *name)
+{
+	u32 bmbase  = 0;
+
+#ifdef DEBUG
+	u8 rev  = 0;
+	pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+	printk(KERN_INFO "XILLEON 210/225/226 IDE:"
+	       " rev %02x IDE UDMA controller on pci%s\n", 
+	       rev, dev->slot_name);
+#endif
+	bmide_dev = dev;
+
+	/* Indicate drives are capable of dma transfers */
+	pci_read_config_dword(bmide_dev, pciideX225_IDE_BM_BASE, &bmbase);
+	bmbase &= 0xfffffff0;
+	outb((inb(bmbase + ioideX225_IDE_PRI_BM_STATUS) | 0x60),
+	     bmbase + ioideX225_IDE_PRI_BM_STATUS);
+	outb((inb(bmbase + ioideX225_IDE_SEC_BM_STATUS) | 0x60),
+	     bmbase + ioideX225_IDE_SEC_BM_STATUS);
+
+	return 0;
+}
+
+/********************************************************
+*
+* max_drive_pio_mode
+*
+* Determine the maximum pio mode supported by this drive
+*
+*********************************************************/
+static byte max_drive_pio_mode (ide_drive_t *drive)
+{
+	unsigned short pio_timing[6] = {960, 480, 240, 180, 120, 90};
+	unsigned short adv_modes     = drive->id->eide_pio_modes;
+	unsigned short iordy_time    = drive->id->eide_pio_iordy;
+	byte mode_mask               = 0x01;
+	byte max_pio = 2;
+
+	if (drive->id->field_valid & 0x02) {
+		/* If the drive supports flow control, use the minimum
+		 * iordy time to find the best pio mode supported by
+		 * the drive. */
+		if (drive->id->eide_pio_iordy > 0) {
+			/* iordy supported, use minimum drive timing to
+			   find best mode. */
+			for (max_pio = 5;
+			     max_pio && iordy_time > pio_timing[max_pio];
+			     max_pio--);
+		} else {
+			/* iordy not supported, use advanced mode support
+			   flags to find best mode. */
+			for (max_pio = 2;
+			     adv_modes & mode_mask; mode_mask <<= 1) {
+				max_pio++;
+			}
+		}
+	}     
+#ifdef DEBUG
+	printk("XILLEON 210/225/226 IDE drive %d, max pio mode = %d\n",
+	       drive->dn, max_pio);
+#endif
+	return max_pio;
+}
+
+/********************************************************
+*
+* max_drive_dma_mode
+*
+* Determine the maximum dma mode supported by this drive
+*
+*********************************************************/
+static byte max_drive_dma_mode (ide_drive_t *drive)
+{
+	unsigned short dma_modes = drive->id->dma_mword;
+	unsigned short mode_mask = 0x80;
+	byte max_dma             = 0;
+
+	if (drive->id->field_valid & 0x02 && dma_modes & 0xff) {
+		for (max_dma = 7;
+		     (dma_modes & mode_mask) == 0; mode_mask >>= 1) {
+			max_dma--;
+		}
+#ifdef DEBUG
+		printk("XILLEON 210/225/226 IDE drive %d,"
+		       " max dma mode = %d\n", drive->dn, max_dma);
+#endif        
+		return max_dma;
+	} else {
+#ifdef DEBUG
+		printk("XILLEON 210/225/226 IDE drive %d,"
+		       " dma not supported\n", drive->dn);
+#endif
+		return 0x0f;
+	}
+}
+
+/********************************************************
+*
+* max_drive_udma_mode
+*
+* Determine the maximum dma mode supported by this drive
+*
+*********************************************************/
+static byte max_drive_udma_mode (ide_drive_t *drive)
+{
+	unsigned short udma_modes = drive->id->dma_ultra;
+	unsigned short mode_mask  = 0x80;
+	byte max_udma             = 0;
+
+	if (drive->id->field_valid & 0x04 && udma_modes & 0xff) {
+		for (max_udma = 7;
+		     (udma_modes & mode_mask) == 0; mode_mask >>= 1) {
+			max_udma--;
+		}
+		if (eighty_ninty_three(drive)) {
+#ifdef DEBUG
+			printk("XILLEON 210/225/226 IDE drive %d,"
+			       " max udma mode = %d\n", drive->dn, max_udma);
+#endif        
+			return max_udma;
+		} else {
+#ifdef DEBUG
+			printk("XILLEON 210/225/226 IDE IDE cable does not"
+			       " support UDMA modes > 2."
+			       "  Drive %d, max udma mode = %d\n",
+			       drive->dn, max_udma > 2 ? 2 : max_udma);
+#endif        
+			return max_udma > 2 ? 2 : max_udma;
+		}
+	} else {
+#ifdef DEBUG
+		printk("XILLEON 210/225/226 IDE drive %d,"
+		       " udma not supported\n", drive->dn);
+#endif
+		return 0x0f;
+	}
+}
+
+
+static int x225_ide_tune_chipset (ide_drive_t *drive, byte speed)
+{
+
+	ide_hwif_t *hwif    = HWIF(drive);
+	struct pci_dev *dev = hwif->pci_dev;
+	int err;
+   
+	u32 work_dword;
+
+	u8 tmg_cntl_reg_off;  /* timing register offset */
+	u8 pio_cntl_reg_off;  /* pio control register offset */
+	u8 pio_mode_reg_off;  /* pio mode register offset */
+	u8 pio_mode_reg;      /* pio mode register contents */
+	u8 pio_mode;          /* pio mode  */
+#if 0
+	u8 pio_control;       /* pio control register */
+#endif
+	u8 dma_mode_reg_off;  /* dma mode register offset */
+	u8 dma_mode;          /* dma mode */
+
+	if (drive->dn > 3)    /* we  support four drives */
+		return -1;
+
+	/* Setup register offsets for current drive */
+	/* Assume drives 0/1 are on primary, 2/3 are on secondary */
+	if (drive->dn > 1) {
+		pio_mode_reg_off = pciideX225_IDE_PIO_MODE+1;
+		pio_cntl_reg_off = pciideX225_IDE_PIO_CONTROL+1;
+		tmg_cntl_reg_off = drive->dn&1 ?
+			pciideX225_IDE_TMG_CNTL+2 : pciideX225_IDE_TMG_CNTL+3;
+		dma_mode_reg_off = drive->dn&1 ?
+			pciideX225_IDE_DMA_MODE+3 : pciideX225_IDE_DMA_MODE+2;
+	} else {
+		pio_mode_reg_off = pciideX225_IDE_PIO_MODE;
+		pio_cntl_reg_off = pciideX225_IDE_PIO_CONTROL;
+		tmg_cntl_reg_off = drive->dn&1 ?
+			pciideX225_IDE_TMG_CNTL : pciideX225_IDE_TMG_CNTL+1;
+		dma_mode_reg_off = drive->dn&1 ?
+			pciideX225_IDE_DMA_MODE+1 : pciideX225_IDE_DMA_MODE;
+	}
+
+	/* Reset auto-calc override so that controller calculates mode
+	   timing. */
+	pci_write_config_byte(dev, tmg_cntl_reg_off, 0x7f);
+
+	/* All three transfer types require pio mode to be set to */
+	/* maximum mode supported by both the drive and controller */
+	/* Get the current contents and clear the mode field for this drive*/
+	pci_read_config_byte(dev, pio_mode_reg_off, &pio_mode_reg);
+	pio_mode_reg = drive->dn&1 ? pio_mode_reg & 0x07 : pio_mode_reg & 0x70;
+	/* Get the highest mode the drive can support */
+	pio_mode   = max_drive_pio_mode(drive);
+
+#if 0
+	/* All three transfer types require udma control to be set/reset */
+	/* according to the transfer mode to be used */
+	/* Get the current contents and clear the enable flag for this drive*/
+	pci_read_config_byte(dev, pciideIDE_UDMA_CONTROL, &udma_control_reg);
+	udma_control_reg = drive->dn ?
+		udma_control_reg & 0xfd : pio_mode_reg & 0xfe;
+#endif
+	switch(speed) {
+        case XFER_PIO_4:
+        case XFER_PIO_3:
+        case XFER_PIO_2:
+        case XFER_PIO_1:
+        case XFER_PIO_0:
+		/* Setting transfer mode to PIO */
+		/* If requested mode is higher than drive supports,
+		   set to highest supported */
+		pio_mode = pio_mode > (speed - XFER_PIO_0) ?
+			speed - XFER_PIO_0 : pio_mode;
+
+#ifdef DEBUG
+		printk("xilleon_ide_tune_chipset for drive %s (%d),"
+		       " pio mode %d\n", drive->name, drive->dn, pio_mode);
+#endif
+
+#if 0
+		/* Enable prefetch and write posting */
+		pci_read_config_byte(dev, pio_cntl_reg_off, &pio_control);
+		pio_control = drive->dn ?
+			pio_control | 0x50 : pio_control | 0xa0;
+		pci_write_config_byte(dev, pio_cntl_reg_off, pio_control);
+#endif
+		break;
+
+        case XFER_MW_DMA_2:
+        case XFER_MW_DMA_1:
+        case XFER_MW_DMA_0:
+		/* Setting transfer mode to Multiword DMA */
+		dma_mode   = speed - XFER_MW_DMA_0;        
+		pci_write_config_byte(dev, dma_mode_reg_off, dma_mode); 
+#ifdef DEBUG
+		printk("xilleon_ide_tune_chipset for drive %s (%d),"
+		       " dma mode %d, pio mode %d\n", 
+		       drive->name, drive->dn, dma_mode, pio_mode);
+#endif
+		break;
+
+        case XFER_UDMA_5:
+        case XFER_UDMA_4:
+        case XFER_UDMA_3:
+        case XFER_UDMA_2:
+        case XFER_UDMA_1:
+        case XFER_UDMA_0:
+		/* Setting transfer mode to Ultra DMA */
+		dma_mode  = (speed - XFER_UDMA_0)|0x10;
+		pci_write_config_byte(dev, dma_mode_reg_off, dma_mode);
+#ifdef DEBUG
+		printk("xilleon_ide_tune_chipset for drive %s (%d),"
+		       " udma mode %d, pio mode %d\n", 
+		       drive->name, drive->dn, (speed - XFER_UDMA_0),
+		       pio_mode);
+#endif
+        default:
+		break;
+	}
+
+	if (!drive->init_speed)
+		drive->init_speed = speed;
+
+	/* Set Read and Write Combining */
+	pci_read_config_dword(dev, pciideX225_IDE_PCI_BUSMASTER_CNTL,
+			      &work_dword);
+	pci_write_config_dword(dev, pciideX225_IDE_PCI_BUSMASTER_CNTL,
+			       work_dword|0x60);
+
+	pio_mode_reg |= drive->dn&1 ? pio_mode << 4 : pio_mode;
+	pci_write_config_byte(dev, pio_mode_reg_off, pio_mode_reg);
+	err = ide_config_drive_speed(drive, speed);
+	drive->current_speed = speed;
+
+#if 0
+	pci_read_config_word(dev, pciideIDE_DEVICE_ID, &work_word);
+	printk("IDE_DEVICE_ID          =     %04x\n", work_word);
+
+	pci_read_config_dword(dev, pciideIDE_TMG_CNTL, &work_dword);
+	printk("IDE_TMG_CNTL           = %08x\n", work_dword);
+
+	pci_read_config_word(dev, pciideIDE_PIO_CONTROL, &work_word);
+	printk("IDE_PIO_CONTROL        =     %04x\n", work_word);
+
+	pci_read_config_word(dev, pciideIDE_PIO_MODE, &work_word);
+	printk("IDE_PIO_MODE           =     %04x\n", work_word);
+ 
+	pci_read_config_dword(dev, pciideIDE_DMA_MODE, &work_dword);
+	printk("IDE_DMA_MODE           = %08x\n", work_dword);
+
+	pci_read_config_dword(dev, pciideIDE_PCI_BUSMASTER_CNTL, &work_dword);
+	printk("IDE_PCI_BUSMASTER_CNTL = %08x\n", work_dword);
+#endif
+
+	return err;
+}
+
+/************************************
+
+config_chipset_for_pio              
+
+Set the controller and drive to the 
+highest pio mode supported by both  
+
+*************************************/
+
+static void config_chipset_for_pio (ide_drive_t *drive)
+{
+	byte speed = XFER_PIO_0 + max_drive_pio_mode (drive);
+
+	(void) x225_ide_tune_chipset(drive, speed);
+
+	drive->current_speed = speed;
+
+#ifdef DEBUG
+	printk("config_chipset_for_pio, speed is %d \n", speed);
+#endif
+}
+
+static void x225_ide_tune_drive (ide_drive_t *drive, byte pio)
+{
+#ifdef DEBUG
+	printk("tune drive %s (%d) for pio %d\n", drive->name, drive->dn, pio);
+#endif
+	(void) x225_ide_tune_chipset(drive, XFER_PIO_0 + pio);
+}
+
+static int config_chipset_for_dma (ide_drive_t *drive)
+{
+	struct hd_driveid *id = drive->id;
+	byte speed = 0x0f;
+
+#ifdef DEBUG
+	printk("config_chipset_for_dma for drive %s (%d)\n",
+	       drive->name, drive->dn);
+#endif
+
+	/* Check if drive supports ultra dma - get highest supported mode */
+	if ((speed = max_drive_udma_mode (drive)) != 0x0f) {
+		speed = speed > 5 ? 5 + XFER_UDMA_0 : speed + XFER_UDMA_0;
+		/* Check if drive supports dma - get highest supported mode */
+	} else if ((speed = max_drive_dma_mode (drive)) != 0x0f) {
+		speed = speed > 2 ? 2 + XFER_MW_DMA_0 : speed + XFER_MW_DMA_0;
+	} 
+	if(speed == 0x0f) {
+		/* Speed not set yet, get max pio mode supported
+		   by the drive. */
+		speed = max_drive_pio_mode (drive);
+		speed = speed > 4 ? 4 + XFER_PIO_0 : speed + XFER_PIO_0;
+	}
+	(void) x225_ide_tune_chipset(drive, speed);
+
+	/* Set return code based on drive id information. */
+	return (((id->dma_ultra & 0xff00 && id->field_valid & 0x04) || 
+		 (id->dma_mword & 0xff00 && id->field_valid & 0x02)) ? 1 : 0);
+}
+
+static int config_drive_xfer_rate (ide_drive_t *drive)
+{
+	struct hd_driveid *id = drive->id;
+	int use_dma = 1;
+	ide_hwif_t *hwif = HWIF(drive);
+    
+#ifdef DEBUG
+	printk("config_drive_xfer_rate for drive %s (%d)\n",
+	       drive->name, drive->dn);
+#endif
+
+	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
+		/* Consult the list of known "bad" drives */
+		if (__ide_dma_bad_drive (drive))
+			use_dma = 0;
+		/* Not in list of bad drives - check udma */
+		else if (id->field_valid & 0x06)
+			/* Try to config ultra dma or multiword dma */
+			use_dma = config_chipset_for_dma(drive);
+
+		if (use_dma)
+			config_chipset_for_pio(drive);
+
+	}
+    
+	return use_dma ?
+		hwif->ide_dma_on(drive) : hwif->ide_dma_off_quietly(drive);
+}
+
+static void ide_outbsync_x22x (ide_drive_t *drive, u8 addr,
+			       unsigned long port)
+{
+	outb(addr, port);
+	wmb();
+}
+
+/*
+ * Init the hwif structure for this controller
+ */
+static void __devinit ide_init_x225 (ide_hwif_t *hwif)
+{
+	if (!hwif->irq) {
+#ifdef CONFIG_XILLEON_IDE_SEC
+		hwif->irq = X225_IDE_INT_SEC;
+#else
+		hwif->irq = X225_IDE_INT;
+#endif
+	}
+	hwif->tuneproc = x225_ide_tune_drive;
+	hwif->speedproc = x225_ide_tune_chipset;
+	hwif->serialized = 1;
+
+	hwif->OUTBSYNC = ide_outbsync_x22x;
+
+
+	if (hwif->dma_base) {
+		if (!noautodma)
+			hwif->autodma = 1;
+		hwif->ide_dma_check = config_drive_xfer_rate;
+		hwif->udma_four = 1;
+	} else {
+		hwif->autodma = 0;
+		hwif->drives[0].autotune = 1;
+		hwif->drives[1].autotune = 1;
+	}
+
+#if defined(CONFIG_PROC_FS)
+	if (!xilleon_proc) {
+		ide_pci_create_host_proc("xilleon", xilleon_ide_get_info);
+		xilleon_proc = 1;
+	}
+#endif /* CONFIG_PROC_FS */
+	return;
+}
+
+static void __devinit ide_dmacapable_x22x(ide_hwif_t *hwif,
+					  unsigned long dmabase)
+{
+	hwif->dma_base = dmabase;
+	ide_setup_dma(hwif, dmabase, 8);
+}
+
+static int __devinit init_setup_x22x (struct pci_dev *dev,
+				      ide_pci_device_t *d)
+{
+	return ide_setup_pci_device(dev, d);
+}
+
+static ide_pci_device_t xilleon_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name         = "X225",
+		.init_setup   = init_setup_x22x,
+		.init_chipset = pci_init_x225_ide,
+		.init_iops    = NULL,
+		.init_hwif    = ide_init_x225,
+		.init_dma     = ide_dmacapable_x22x,
+		.channels     = 1,
+		.autodma      = AUTODMA,
+		.enablebits   = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+		.bootable     = ON_BOARD,
+		.extra	      = 0,
+	},{	/* 1 */
+		.name	      = "X226",
+		.init_setup   = init_setup_x22x,
+		.init_chipset = pci_init_x225_ide,
+		.init_iops    = NULL,
+		.init_hwif    = ide_init_x225,
+		.init_dma     = ide_dmacapable_x22x,
+		.channels     = 1,
+		.autodma      = AUTODMA,
+		.enablebits   = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+		.bootable     = ON_BOARD,
+		.extra	      = 0,
+	},{	/* 2 */
+		.name	      = "X210",
+		.init_setup   = init_setup_x22x,
+		.init_chipset = pci_init_x225_ide,
+		.init_iops    = NULL,
+		.init_hwif    = ide_init_x225,
+		.init_dma     = ide_dmacapable_x22x,
+		.channels     = 1,
+		.autodma      = AUTODMA,
+		.enablebits   = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+		.bootable     = ON_BOARD,
+		.extra	      = 0,
+	}
+};
+
+static struct pci_device_id xilleon_pci_tbl[] __devinitdata = {
+        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_X225_IDE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_X226_IDE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_X210_IDE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+        { 0, },
+};
+
+ 
+static int __devinit xilleon_init_one(struct pci_dev *dev,
+				      const struct pci_device_id *id)
+{
+	ide_pci_device_t *d = &xilleon_chipsets[id->driver_data];
+	return ide_setup_pci_device(dev, d);
+}
+
+static struct pci_driver driver = {
+        .name     = "xilleon_ide",
+        .id_table = xilleon_pci_tbl,
+        .probe    = xilleon_init_one,
+};
+
+
+static int xilleon_ide_init(void)
+{
+        return ide_pci_register_driver(&driver);
+}
+ 
+static void xilleon_ide_exit(void)
+{
+        ide_pci_unregister_driver(&driver);
+}
+ 
+module_init(xilleon_ide_init);
+module_exit(xilleon_ide_exit);
+
+MODULE_DESCRIPTION("PCI driver module for Xilleon IDE");
+MODULE_LICENSE("GPL");


 




[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux