patch-2.4.6 linux/arch/cris/drivers/ide.c
Next file: linux/arch/i386/boot/tools/build.c
Previous file: linux/arch/cris/cris.ld
Back to the patch index
Back to the overall index
- Lines: 329
- Date:
Mon Jun 11 19:15:27 2001
- Orig file:
v2.4.5/linux/arch/cris/drivers/ide.c
- Orig date:
Fri Apr 6 10:42:55 2001
diff -u --recursive --new-file v2.4.5/linux/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
@@ -1,4 +1,4 @@
-/* $Id: ide.c,v 1.9 2001/03/01 13:11:18 bjornw Exp $
+/* $Id: ide.c,v 1.16 2001/04/05 08:30:07 matsfg 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,28 @@
* Mikael Starvik (pio setup stuff)
*
* $Log: ide.c,v $
+ * Revision 1.16 2001/04/05 08:30:07 matsfg
+ * Corrected cse1 and csp0 reset.
+ *
+ * Revision 1.15 2001/04/04 14:34:06 bjornw
+ * Re-instated code that mysteriously disappeared during review updates.
+ *
+ * Revision 1.14 2001/04/04 13:45:12 matsfg
+ * Calls REG_SHADOW_SET for cse1 reset so only the resetbit is affected
+ *
+ * Revision 1.13 2001/04/04 13:26:40 matsfg
+ * memmapping is done in init.c
+ *
+ * Revision 1.12 2001/04/04 11:37:56 markusl
+ * Updated according to review remarks
+ *
+ * Revision 1.11 2001/03/29 12:49:14 matsfg
+ * Changed check for ata_tot_size from >= to >.
+ * Sets sw_len to 0 if size is exactly 65536.
+ *
+ * Revision 1.10 2001/03/16 09:39:30 matsfg
+ * Support for reset on port CSP0
+ *
* Revision 1.9 2001/03/01 13:11:18 bjornw
* 100 -> HZ
*
@@ -158,6 +180,10 @@
#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);
+
/*
* good_dma_drives() lists the model names (from "hdparm -i")
* of drives which do not support mword2 DMA but which are
@@ -174,7 +200,7 @@
unsigned long flags;
pio = 4;
- //pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+ /* pio = ide_get_best_pio_mode(drive, pio, 4, NULL); */
save_flags(flags);
cli();
@@ -226,10 +252,6 @@
restore_flags(flags);
}
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive); /* defined below */
-static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
- void *buffer, unsigned int length); /* defined below */
-
void __init
init_e100_ide (void)
{
@@ -277,26 +299,23 @@
*R_GEN_CONFIG = genconfig_shadow;
#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-#ifndef CONFIG_CRIS_LOW_MAP
- /* remap the I/O-mapped reset-bit from CSE1 to something inside our kernel space */
- reset_addr = (unsigned long *)ioremap((unsigned long)(MEM_CSE1_START |
- MEM_NON_CACHEABLE), 16);
- *reset_addr = 0;
-#else
- /* LOW_MAP, can't do the ioremap, but it's already mapped straight over */
- reset_addr = (unsigned long *)(MEM_CSE1_START | MEM_NON_CACHEABLE);
- *reset_addr = 0;
+ 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
/* wait some */
-
- dummy = 1;
- dummy = 2;
- dummy = 3;
+ udelay(25);
#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
- *reset_addr = 1 << 16;
+ REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 1);
+#endif
+#ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
+ REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 1);
#endif
#ifdef CONFIG_ETRAX_IDE_G27_RESET
*R_PORT_G_DATA = 0; /* de-assert bus-reset */
@@ -349,7 +368,6 @@
e100_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
{
ide_ioreg_t data_reg = IDE_DATA_REG;
- unsigned long status;
D(printk("atapi_input_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
data_reg, buffer, bytecount));
@@ -376,7 +394,7 @@
/* initiate a multi word dma read using PIO handshaking */
- *R_ATA_TRANSFER_CNT = bytecount >> 1;
+ *R_ATA_TRANSFER_CNT = IO_FIELD(R_ATA_TRANSFER_CNT, count, bytecount >> 1);
*R_ATA_CTRL_DATA = data_reg |
IO_STATE(R_ATA_CTRL_DATA, rw, read) |
@@ -390,35 +408,38 @@
LED_DISK_READ(1);
WAIT_DMA(3);
LED_DISK_READ(0);
-
+
#if 0
- /* old polled transfer code */
-
- /* initiate a multi word read */
-
- *R_ATA_TRANSFER_CNT = wcount << 1;
-
- *R_ATA_CTRL_DATA = data_reg |
- IO_STATE(R_ATA_CTRL_DATA, rw, read) |
- IO_STATE(R_ATA_CTRL_DATA, src_dst, register) |
- IO_STATE(R_ATA_CTRL_DATA, handsh, pio) |
- IO_STATE(R_ATA_CTRL_DATA, multi, on) |
- IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-
- /* svinto has a latency until the busy bit actually is set */
-
- nop(); nop();
- nop(); nop();
- nop(); nop();
- nop(); nop();
- nop(); nop();
-
- /* unit should be busy during multi transfer */
- while((status = *R_ATA_STATUS_DATA) & IO_MASK(R_ATA_STATUS_DATA, busy)) {
- while(!(status & IO_MASK(R_ATA_STATUS_DATA, dav)))
- status = *R_ATA_STATUS_DATA;
- *ptr++ = (unsigned short)(status & 0xffff);
- }
+ /* old polled transfer code
+ * this should be moved into a new function that can do polled
+ * transfers if DMA is not available
+ */
+
+ /* initiate a multi word read */
+
+ *R_ATA_TRANSFER_CNT = wcount << 1;
+
+ *R_ATA_CTRL_DATA = data_reg |
+ IO_STATE(R_ATA_CTRL_DATA, rw, read) |
+ IO_STATE(R_ATA_CTRL_DATA, src_dst, register) |
+ IO_STATE(R_ATA_CTRL_DATA, handsh, pio) |
+ IO_STATE(R_ATA_CTRL_DATA, multi, on) |
+ IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+
+ /* svinto has a latency until the busy bit actually is set */
+
+ nop(); nop();
+ nop(); nop();
+ nop(); nop();
+ nop(); nop();
+ nop(); nop();
+
+ /* unit should be busy during multi transfer */
+ while((status = *R_ATA_STATUS_DATA) & IO_MASK(R_ATA_STATUS_DATA, busy)) {
+ while(!(status & IO_MASK(R_ATA_STATUS_DATA, dav)))
+ status = *R_ATA_STATUS_DATA;
+ *ptr++ = (unsigned short)(status & 0xffff);
+ }
#endif
}
@@ -426,8 +447,6 @@
e100_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
{
ide_ioreg_t data_reg = IDE_DATA_REG;
- unsigned short *ptr = (unsigned short *)buffer;
- unsigned long ctrl;
D(printk("atapi_output_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
data_reg, buffer, bytecount));
@@ -454,7 +473,7 @@
/* initiate a multi word dma write using PIO handshaking */
- *R_ATA_TRANSFER_CNT = bytecount >> 1;
+ *R_ATA_TRANSFER_CNT = IO_FIELD(R_ATA_TRANSFER_CNT, count, bytecount >> 1);
*R_ATA_CTRL_DATA = data_reg |
IO_STATE(R_ATA_CTRL_DATA, rw, write) |
@@ -470,40 +489,42 @@
LED_DISK_WRITE(0);
#if 0
- /* old polled write code */
+ /* old polled write code - see comment in input_bytes */
- while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+ /* wait for busy flag */
+ while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
- /* initiate a multi word write */
+ /* initiate a multi word write */
- *R_ATA_TRANSFER_CNT = bytecount >> 1;
+ *R_ATA_TRANSFER_CNT = bytecount >> 1;
- ctrl = data_reg |
- IO_STATE(R_ATA_CTRL_DATA, rw, write) |
- IO_STATE(R_ATA_CTRL_DATA, src_dst, register) |
- IO_STATE(R_ATA_CTRL_DATA, handsh, pio) |
- IO_STATE(R_ATA_CTRL_DATA, multi, on) |
- IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-
- 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.
- * 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
- * and then tr_rdy would be 0 forever. This is solved by checking busy
- * in the inner loop.
- */
-
- do {
- *R_ATA_CTRL_DATA = ctrl | *ptr++;
- while(!(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy)) &&
- (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)));
- } while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
+ ctrl = data_reg |
+ IO_STATE(R_ATA_CTRL_DATA, rw, write) |
+ IO_STATE(R_ATA_CTRL_DATA, src_dst, register) |
+ IO_STATE(R_ATA_CTRL_DATA, handsh, pio) |
+ IO_STATE(R_ATA_CTRL_DATA, multi, on) |
+ IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+
+ 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.
+ * 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
+ * and then tr_rdy would be 0 forever. This is solved by checking busy
+ * in the inner loop.
+ */
+
+ do {
+ *R_ATA_CTRL_DATA = ctrl | *ptr++;
+ while(!(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy)) &&
+ (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)));
+ } while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
+
+ LED_DISK_WRITE(0);
+#endif
- LED_DISK_WRITE(0);
-#endif
}
/*
@@ -604,7 +625,7 @@
those blocks that were actually set-up for transfer.
*/
- if(ata_tot_size + size >= 131072) {
+ if(ata_tot_size + size > 131072) {
printk("too large total ATA DMA request, %d + %d!\n", ata_tot_size, size);
return 1;
}
@@ -625,7 +646,12 @@
addr += 65536;
}
/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
- ata_descrs[count].sw_len = size;
+ if(size == 65536) {
+ ata_descrs[count].sw_len = 0; /* 0 means 65536, this is a 16-bit field */
+ }
+ else {
+ ata_descrs[count].sw_len = size;
+ }
ata_descrs[count].ctrl = 0;
ata_descrs[count].buf = addr;
ata_descrs[count].next = virt_to_phys(&ata_descrs[count + 1]);
@@ -793,9 +819,11 @@
/* initiate a multi word dma read using DMA handshaking */
- *R_ATA_TRANSFER_CNT = ata_tot_size >> 1;
+ *R_ATA_TRANSFER_CNT =
+ IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
- *R_ATA_CTRL_DATA = IDE_DATA_REG |
+ *R_ATA_CTRL_DATA =
+ IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
IO_STATE(R_ATA_CTRL_DATA, rw, read) |
IO_STATE(R_ATA_CTRL_DATA, src_dst, dma) |
IO_STATE(R_ATA_CTRL_DATA, handsh, dma) |
@@ -834,9 +862,11 @@
/* initiate a multi word dma write using DMA handshaking */
- *R_ATA_TRANSFER_CNT = ata_tot_size >> 1;
+ *R_ATA_TRANSFER_CNT =
+ IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
- *R_ATA_CTRL_DATA = IDE_DATA_REG |
+ *R_ATA_CTRL_DATA =
+ IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
IO_STATE(R_ATA_CTRL_DATA, rw, write) |
IO_STATE(R_ATA_CTRL_DATA, src_dst, dma) |
IO_STATE(R_ATA_CTRL_DATA, handsh, dma) |
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)