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
- Lines: 336
- Date:
2003-08-25 04:44:39.000000000 -0700
- Orig file:
linux-2.4.21/arch/cris/drivers/ide.c
- Orig date:
2003-06-13 07:51:29.000000000 -0700
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)