patch-2.4.22 linux-2.4.22/arch/cris/drivers/ide.c

Next file: linux-2.4.22/arch/cris/drivers/lpslave/bintocarr.pl
Previous file: linux-2.4.22/arch/cris/drivers/i2c.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/arch/cris/drivers/ide.c linux-2.4.22/arch/cris/drivers/ide.c
@@ -1,4 +1,4 @@
-/* $Id: ide.c,v 1.26 2002/09/17 12:16:59 bjornw Exp $
+/* $Id: ide.c,v 1.30 2003/07/08 07:24:47 pkj 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.
@@ -8,6 +8,19 @@
  *             Mikael Starvik     (pio setup stuff)
  *
  * $Log: ide.c,v $
+ * Revision 1.30  2003/07/08 07:24:47  pkj
+ * Corrected spelling mistakes originally found in 2.5.x
+ *
+ * Revision 1.29  2003/06/17 13:57:49  starvik
+ * Merge of Linux 2.4.21
+ *
+ * Revision 1.28  2003/01/22 12:41:12  starvik
+ * Added LBA48 support
+ * Fixed typo in e100_ideproc
+ *
+ * Revision 1.27  2003/01/09 18:03:47  starvik
+ * init_ioremap is now called by kernel before device drivers are initialized
+ *
  * Revision 1.26  2002/09/17 12:16:59  bjornw
  * Removed unnecessary cli/sti pair
  *
@@ -151,6 +164,8 @@
 static volatile unsigned long *reset_addr;
 #endif
 
+static int e100_read_command = 0;
+
 #define LOWDB(x)
 #define D(x) 
 
@@ -186,14 +201,9 @@
 			    IO_MASK(R_ATA_STATUS_DATA, tr_rdy)))
 		timeleft--;
 }
-unsigned char 
-IN_BYTE(ide_ioreg_t reg) {
-        /* data was in the lower 16 bits in the status reg */
-        return (unsigned char)(IN_WORD(reg));
-}
 
 unsigned short 
-IN_WORD(ide_ioreg_t reg) {
+IN_BYTE(ide_ioreg_t reg) {
 	int status;
 	int timeleft;
 
@@ -237,7 +247,7 @@
 
 	LOWDB(printk("inb: 0x%x from reg 0x%x\n", status & 0xff, reg));
 
-        return (unsigned short)status;
+        return (unsigned char)status;
 }
 
 /* PIO timing (in R_ATA_CONFIG)
@@ -292,9 +302,15 @@
 #define ATA_PIO0_STROBE 19
 #define ATA_PIO0_HOLD    4
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
-static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
-			  void *buffer, unsigned int length);
+static int e100_dma_check (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);
+static void e100_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
 
 /*
  * good_dma_drives() lists the model names (from "hdparm -i")
@@ -309,8 +325,6 @@
 
 static void tune_e100_ide(ide_drive_t *drive, byte pio)
 {
-	unsigned long flags;
-	
 	pio = 4;
 	/* pio = ide_get_best_pio_mode(drive, pio, 4, NULL); */
 	
@@ -374,8 +388,15 @@
 		ide_hwif_t *hwif = &ide_hwifs[h];
 		hwif->chipset = ide_etrax100;
 		hwif->tuneproc = &tune_e100_ide;
-		hwif->dmaproc = &e100_dmaproc;
-		hwif->ideproc = &e100_ideproc;
+                hwif->ata_input_data = &e100_ide_input_data;
+                hwif->ata_output_data = &e100_ide_output_data;
+                hwif->atapi_input_bytes = &e100_atapi_input_bytes;
+                hwif->atapi_output_bytes = &e100_atapi_output_bytes;
+                hwif->ide_dma_check = &e100_dma_check;
+                hwif->ide_dma_end = &e100_dma_end;
+		hwif->ide_dma_write = &e100_dma_write;
+		hwif->ide_dma_read = &e100_dma_read;
+		hwif->ide_dma_begin = &e100_dma_begin;
 	}
 
 	/* actually reset and configure the etrax100 ide/ata interface */
@@ -400,11 +421,9 @@
         REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 0);
 #endif 
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-        init_ioremap();
         REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 0);
 #endif
 #ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
-        init_ioremap();
         REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 0);
 #endif
 #ifdef CONFIG_ETRAX_IDE_PB7_RESET  
@@ -618,7 +637,7 @@
         LED_DISK_WRITE(1);
         
         /* Etrax will set busy = 1 until the multi pio transfer has finished
-         * and tr_rdy = 1 after each succesful word transfer. 
+         * and tr_rdy = 1 after each successful word transfer.
          * When the last byte has been transferred Etrax will first set tr_tdy = 1 
          * and then busy = 0 (not in the same cycle). If we read busy before it
          * has been set to 0 we will think that we should transfer more bytes 
@@ -655,32 +674,6 @@
 	e100_atapi_output_bytes(drive, buffer, wcount << 2);
 }
 
-/*
- * The multiplexor for ide_xxxput_data and atapi calls
- */
-static void 
-e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
-	      void *buffer, unsigned int length)
-{
-	switch (func) {
-		case ideproc_ide_input_data:
-			e100_ide_input_data(drive, buffer, length);
-			break;
-		case ideproc_ide_output_data:
-			e100_ide_input_data(drive, buffer, length);
-			break;
-		case ideproc_atapi_input_bytes:
-			e100_atapi_input_bytes(drive, buffer, length);
-			break;
-		case ideproc_atapi_output_bytes:
-			e100_atapi_output_bytes(drive, buffer, length);
-			break;
-		default:
-			printk("e100_ideproc: unsupported func %d!\n", func);
-			break;
-	}
-}
-
 /* we only have one DMA channel on the chip for ATA, so we can keep these statically */
 static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS];
 static unsigned int ata_tot_size;
@@ -815,8 +808,8 @@
 	LED_DISK_READ(0);
 	LED_DISK_WRITE(0);
 
-	dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive);
-	stat = GET_STAT();			/* get drive status */
+	dma_stat = HWIF(drive)->ide_dma_end(drive);
+	stat = HWIF(drive)->INB(IDE_STATUS_REG);		/* get drive status */
 	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
 		if (!dma_stat) {
 			struct request *rq;
@@ -833,7 +826,7 @@
 }
 
 /*
- * e100_dmaproc() initiates/aborts DMA read/write operations on a drive.
+ * Functions below initiates/aborts DMA read/write operations on a drive.
  *
  * The caller is assumed to have selected the drive and programmed the drive's
  * sector address using CHS or LBA.  All that remains is to prepare for DMA
@@ -848,59 +841,19 @@
  * the caller should revert to PIO for the current request.
  */
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+static int e100_dma_check(ide_drive_t *drive)
 {
-        static unsigned int reading; /* static to support ide_dma_begin semantics */
-	int atapi = 0;
-
-	D(printk("e100_dmaproc func %d\n", func));
-
-        switch (func) {
-		case ide_dma_verbose:
-			return 0;
-                case ide_dma_check:
-                        return config_drive_for_dma (drive);
-		case ide_dma_off:
-		case ide_dma_off_quietly:
-			/* ok.. we don't really need to do anything I think. */
-			return 0;
-                case ide_dma_write:
-                        reading = 0;
-			break;
-                case ide_dma_read:
-			reading = 1;
-                        break;
-                case ide_dma_begin:
-			/* 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. 
-			 */
-			atapi++;
-			goto dma_begin;
-		case ide_dma_end: /* returns 1 on error, 0 otherwise */
-			/* TODO: check if something went wrong with the DMA */
-			return 0;
-
-                default:
-                        printk("e100_dmaproc: unsupported func %d\n", func);
-                        return 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 config_drive_for_dma (drive);
+}
 
- dma_begin:
+static int e100_dma_end(ide_drive_t *drive)
+{
+	/* TODO: check if something went wrong with the DMA */
+	return 0;
+}
 
+static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
+{
 	if(reading) {
 
 		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
@@ -917,8 +870,15 @@
 			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
 			
 			/* issue cmd to drive */
-			
-			OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
+                        if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				OUT_BYTE(WIN_READDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
+			}
 		}
 
 		/* begin DMA */
@@ -968,8 +928,15 @@
 			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
 			
 			/* issue cmd to drive */
-			
-			OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
+			if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				OUT_BYTE(WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
+			}
 		}
 
 		/* begin DMA */
@@ -994,14 +961,44 @@
 
 		D(printk("dma write of %d bytes.\n", ata_tot_size));
 	}
-
-	/* DMA started successfully */
 	return 0;
 }
 
-/* ide.c calls this, but we don't need to do anything particular */
+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);
+}
 
-int ide_release_dma (ide_hwif_t *hwif)
+static int e100_dma_begin(ide_drive_t *drive)
 {
-	return 1;
+	/* 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);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)