

This is a multi-part message in MIME format.

------=_NextPart_000_0041_01C4C57D.A0B5F640
Content-Type: text/plain;
	charset="us-ascii"
Content-Transfer-Encoding: 7bit

Updated IDE driver for Linux 2.6.9.

Signed-off-by: Mikael Starvik <starvik@axis.com>

------=_NextPart_000_0041_01C4C57D.A0B5F640
Content-Type: application/octet-stream;
	name="cris269_4.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="cris269_4.patch"

../linux/arch/cris/arch-v10/drivers/ide.c =
lx25/arch/cris/arch-v10/drivers/ide.c
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 /dev/null                                |    0 
 25-akpm/arch/cris/arch-v10/drivers/ide.c |  179 +++++++++++++++++++++----------
 2 files changed, 124 insertions(+), 55 deletions(-)

diff -puN arch/cris/arch-v10/drivers/ide.c~cris-architecture-update-ide-driver arch/cris/arch-v10/drivers/ide.c
--- 25/arch/cris/arch-v10/drivers/ide.c~cris-architecture-update-ide-driver	Mon Nov  8 14:19:28 2004
+++ 25-akpm/arch/cris/arch-v10/drivers/ide.c	Mon Nov  8 14:19:28 2004
@@ -1,4 +1,4 @@
-/* $Id: ide.c,v 1.1 2004/01/22 08:22:58 starvik Exp $
+/* $Id: ide.c,v 1.4 2004/10/12 07:55:48 starvik Exp $
  *
  * Etrax specific IDE functions, like init and PIO-mode setting etc.
  * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
@@ -30,7 +30,6 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/init.h>
-#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/arch/svinto.h>
@@ -46,18 +45,13 @@
 
 #define IDE_REGISTER_TIMEOUT 300
 
-#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-/* address where the memory-mapped IDE reset bit lives, if used */
-static volatile unsigned long *reset_addr;
-#endif
-
 static int e100_read_command = 0;
 
 #define LOWDB(x)
 #define D(x)
 
 void
-etrax100_ide_outw(unsigned short data, ide_ioreg_t reg) {
+etrax100_ide_outw(unsigned short data, unsigned long reg) {
 	int timeleft;
 	LOWDB(printk("ow: data 0x%x, reg 0x%x\n", data, reg));
 
@@ -90,7 +84,7 @@ etrax100_ide_outw(unsigned short data, i
 }
 
 void
-etrax100_ide_outb(unsigned char data, ide_ioreg_t reg)
+etrax100_ide_outb(unsigned char data, unsigned long reg)
 {
 	etrax100_ide_outw(data, reg);
 }
@@ -102,7 +96,7 @@ etrax100_ide_outbsync(ide_drive_t *drive
 }
 
 unsigned short
-etrax100_ide_inw(ide_ioreg_t reg) {
+etrax100_ide_inw(unsigned long reg) {
 	int status;
 	int timeleft;
 
@@ -150,7 +144,7 @@ etrax100_ide_inw(ide_ioreg_t reg) {
 }
 
 unsigned char
-etrax100_ide_inb(ide_ioreg_t reg)
+etrax100_ide_inb(unsigned long reg)
 {
 	return (unsigned char)etrax100_ide_inw(reg);
 }
@@ -208,8 +202,10 @@ etrax100_ide_inb(ide_ioreg_t reg)
 #define ATA_PIO0_HOLD    4
 
 static int e100_dma_check (ide_drive_t *drive);
-static void e100_dma_start(ide_drive_t *drive);
+static int e100_dma_begin (ide_drive_t *drive);
 static int e100_dma_end (ide_drive_t *drive);
+static int e100_dma_read (ide_drive_t *drive);
+static int e100_dma_write (ide_drive_t *drive);
 static void e100_ide_input_data (ide_drive_t *drive, void *, unsigned int);
 static void e100_ide_output_data (ide_drive_t *drive, void *, unsigned int);
 static void e100_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
@@ -280,40 +276,6 @@ static void tune_e100_ide(ide_drive_t *d
 	}
 }
 
-static int e100_dma_setup(ide_drive_t *drive)
-{
-	struct request *rq = drive->hwif->hwgroup->rq;
-
-	if (rq_data_dir(rq)) {
-		e100_read_command = 0;
-
-		RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(ATA_TX_DMA_NBR);
-	} else {
-		e100_read_command = 1;
-
-		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(ATA_RX_DMA_NBR);
-	}
-
-	/* set up the Etrax DMA descriptors */
-	if (e100_ide_build_dmatable(drive)) {
-		ide_map_sg(drive, rq);
-		return 1;
-	}
-
-	return 0;
-}
-
-static void e100_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
-	/* set the irq handler which will finish the request when DMA is done */
-	ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
-
-	/* issue cmd to drive */
-	etrax100_ide_outb(command, IDE_COMMAND_REG);
-}
-
 void __init
 init_e100_ide (void)
 {
@@ -335,9 +297,9 @@ init_e100_ide (void)
                 hwif->atapi_output_bytes = &e100_atapi_output_bytes;
                 hwif->ide_dma_check = &e100_dma_check;
                 hwif->ide_dma_end = &e100_dma_end;
-		hwif->dma_setup = &e100_dma_setup;
-		hwif->dma_exec_cmd = &e100_dma_exec_cmd;
-		hwif->dma_start = &e100_dma_start;
+		hwif->ide_dma_write = &e100_dma_write;
+		hwif->ide_dma_read = &e100_dma_read;
+		hwif->ide_dma_begin = &e100_dma_begin;
 		hwif->OUTB = &etrax100_ide_outb;
 		hwif->OUTW = &etrax100_ide_outw;
 		hwif->OUTBSYNC = &etrax100_ide_outbsync;
@@ -457,7 +419,7 @@ static etrax_dma_descr mydescr;
 static void
 e100_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
 {
-	ide_ioreg_t data_reg = IDE_DATA_REG;
+	unsigned long data_reg = IDE_DATA_REG;
 
 	D(printk("atapi_input_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
 		 data_reg, buffer, bytecount));
@@ -536,7 +498,7 @@ e100_atapi_input_bytes (ide_drive_t *dri
 static void
 e100_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
 {
-	ide_ioreg_t data_reg = IDE_DATA_REG;
+	unsigned long data_reg = IDE_DATA_REG;
 
 	D(printk("atapi_output_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
 		 data_reg, buffer, bytecount));
@@ -656,9 +618,20 @@ static int e100_ide_build_dmatable (ide_
 
 	ata_tot_size = 0;
 
-	ide_map_sg(drive, rq);
+	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
+		u8 *virt_addr = rq->buffer;
+		int sector_count = rq->nr_sectors;
+		memset(&sg[0], 0, sizeof(*sg));
+		sg[0].page = virt_to_page(virt_addr);
+		sg[0].offset = offset_in_page(virt_addr);
+		sg[0].length =  sector_count  * SECTOR_SIZE;
+		hwif->sg_nents = i = 1;
+	}
+	else
+	{
+		hwif->sg_nents = i = blk_rq_map_sg(drive->queue, rq, hwif->sg_table);
+	}
 
-	i = hwif->sg_nents;
 
 	while(i) {
 		/*
@@ -795,6 +768,10 @@ static ide_startstop_t etrax_dma_intr (i
  * sector address using CHS or LBA.  All that remains is to prepare for DMA
  * and then issue the actual read/write DMA/PIO command to the drive.
  *
+ * For ATAPI devices, we just prepare for DMA and return. The caller should
+ * then issue the packet command to the drive and call us again with
+ * ide_dma_begin afterwards.
+ *
  * Returns 0 if all went well.
  * Returns 1 if DMA read/write could not be started, in which case
  * the caller should revert to PIO for the current request.
@@ -811,9 +788,35 @@ static int e100_dma_end(ide_drive_t *dri
 	return 0;
 }
 
-static void e100_dma_start(ide_drive_t *drive)
+static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
 {
-	if (e100_read_command) {
+	if(reading) {
+
+		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_RX_DMA_NBR);
+
+		/* set up the Etrax DMA descriptors */
+
+		if(e100_ide_build_dmatable (drive))
+			return 1;
+
+		if(!atapi) {
+			/* set the irq handler which will finish the request when DMA is done */
+
+			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
+
+			/* issue cmd to drive */
+                        if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				etrax100_ide_outb(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				etrax100_ide_outb(WIN_READDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				etrax100_ide_outb(WIN_READDMA, IDE_COMMAND_REG);
+			}
+		}
+
 		/* begin DMA */
 
 		/* need to do this before RX DMA due to a chip bug
@@ -846,6 +849,32 @@ static void e100_dma_start(ide_drive_t *
 
 	} else {
 		/* writing */
+
+		RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_TX_DMA_NBR);
+
+		/* set up the Etrax DMA descriptors */
+
+		if(e100_ide_build_dmatable (drive))
+			return 1;
+
+		if(!atapi) {
+			/* set the irq handler which will finish the request when DMA is done */
+
+			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
+
+			/* issue cmd to drive */
+			if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				etrax100_ide_outb(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				etrax100_ide_outb(WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				etrax100_ide_outb(WIN_WRITEDMA, IDE_COMMAND_REG);
+			}
+		}
+
 		/* begin DMA */
 
 		*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs);
@@ -868,4 +897,44 @@ static void e100_dma_start(ide_drive_t *
 
 		D(printk("dma write of %d bytes.\n", ata_tot_size));
 	}
+	return 0;
+}
+
+static int e100_dma_write(ide_drive_t *drive)
+{
+	e100_read_command = 0;
+	/* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
+	 * then they call ide_dma_begin after they have issued the appropriate drive command
+	 * themselves to actually start the chipset DMA. so we just return here if we're
+	 * not a diskdrive.
+	 */
+	if (drive->media != ide_disk)
+                return 0;
+	return e100_start_dma(drive, 0, 0);
+}
+
+static int e100_dma_read(ide_drive_t *drive)
+{
+	e100_read_command = 1;
+	/* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
+	 * then they call ide_dma_begin after they have issued the appropriate drive command
+	 * themselves to actually start the chipset DMA. so we just return here if we're
+	 * not a diskdrive.
+	 */
+	if (drive->media != ide_disk)
+                return 0;
+	return e100_start_dma(drive, 0, 1);
+}
+
+static int e100_dma_begin(ide_drive_t *drive)
+{
+	/* begin DMA, used by ATAPI devices which want to issue the
+	 * appropriate IDE command themselves.
+	 *
+	 * they have already called ide_dma_read/write to set the
+	 * static reading flag, now they call ide_dma_begin to do
+	 * the real stuff. we tell our code below not to issue
+	 * any IDE commands itself and jump into it.
+	 */
+	 return e100_start_dma(drive, 1, e100_read_command);
 }
diff -L linux/arch/cris/arch-v10/drivers/ide.c -puN /dev/null /dev/null
_
