2.4 IDE driver code for m68k
diff mbox series

Message ID 200304131305.h3DD5Drj001281@callisto.of.borg
State New, archived
Headers show
Series
  • 2.4 IDE driver code for m68k
Related show

Commit Message

Geert Uytterhoeven April 13, 2003, 1:05 p.m. UTC
IDE driver and architecture specific updates for m68k:
  - Atari Falcon IDE: Add falconide_intr_lock
  - Amiga A1200/A4000 Gayle IDE: Set hwif->mmio = 2 to prevent the generic IDE
    code from messing with resources
  - Q40 IDE: Fix resource handling, so the interface shows up in /proc/ioports
    while we do use MMIO ops (from Richard Zidlicky)
  - ide_ioreg_t is unsigned long
  - Always use MMIO IDE operations, since so far no single m68k platform uses
    ISA/PCI I/O space for IDE.
  - Make ide_{get,release}_lock() handling completely Atari Falcon-specific
  - Define ide_ack_intr() and set IDE_ARCH_ACK_INTR


Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Patch
diff mbox series

--- linux-2.4.21-pre7/drivers/ide/legacy/falconide.c	Thu Feb 27 10:15:46 2003
+++ linux-m68k-2.4.21-pre7/drivers/ide/legacy/falconide.c	Sun Mar 30 22:22:40 2003
@@ -49,6 +49,14 @@ 
 
 
     /*
+     *  falconide_intr_lock is used to obtain access to the IDE interrupt,
+     *  which is shared between several drivers.
+     */
+
+int falconide_intr_lock;
+
+
+    /*
      *  Probe for a Falcon IDE interface
      */
 
--- linux-2.4.21-pre7/drivers/ide/legacy/gayle.c	Thu Feb 27 10:15:46 2003
+++ linux-m68k-2.4.21-pre7/drivers/ide/legacy/gayle.c	Sun Mar 30 22:22:40 2003
@@ -125,6 +125,7 @@ 
 	ide_ioreg_t base, ctrlport, irqport;
 	ide_ack_intr_t *ack_intr;
 	hw_regs_t hw;
+	ide_hwif_t *hwif;
 	int index;
 	unsigned long phys_base, res_start, res_n;
 
@@ -154,11 +155,12 @@ 
 
 	ide_setup_ports(&hw, base, gayle_offsets,
 			ctrlport, irqport, ack_intr,
-//			gaule_iops,
+//			&gayle_iops,
 			IRQ_AMIGA_PORTS);
 
-	index = ide_register_hw(&hw, NULL);
+	index = ide_register_hw(&hw, &hwif);
 	if (index != -1) {
+	    hwif->mmio = 2;
 	    switch (i) {
 		case 0:
 		    printk("ide%d: Gayle IDE interface (A%d style)\n", index,
--- linux-2.4.21-pre7/drivers/ide/legacy/q40ide.c	Thu Feb 27 10:15:46 2003
+++ linux-m68k-2.4.21-pre7/drivers/ide/legacy/q40ide.c	Wed Apr  9 14:41:28 2003
@@ -31,7 +31,7 @@ 
 #define PCIDE_BASE5	0x1e0
 #define PCIDE_BASE6	0x160
 
-static const q40ide_ioreg_t pcide_bases[Q40IDE_NUM_HWIFS] = {
+static const ide_ioreg_t pcide_bases[Q40IDE_NUM_HWIFS] = {
     PCIDE_BASE1, PCIDE_BASE2, /* PCIDE_BASE3, PCIDE_BASE4  , PCIDE_BASE5,
     PCIDE_BASE6 */
 };
@@ -41,23 +41,21 @@ 
      *  Offsets from one of the above bases
      */
 
+/* used to do addr translation here but it is easier to do in setup ports */
+/*#define IDE_OFF_B(x)	((unsigned long)Q40_ISA_IO_B((IDE_##x##_OFFSET)))*/
 
-/* HD_DATA was redefined in asm-m68k/ide.h */
-#undef HD_DATA
-#define HD_DATA  0x1f0
-
-
-#define PCIDE_REG(x)	((q40ide_ioreg_t)(HD_##x-PCIDE_BASE1))
+#define IDE_OFF_B(x)	((ide_ioreg_t)((IDE_##x##_OFFSET)))
+#define IDE_OFF_W(x)	((ide_ioreg_t)((IDE_##x##_OFFSET)))
 
 static const int pcide_offsets[IDE_NR_PORTS] = {
-    PCIDE_REG(DATA), PCIDE_REG(ERROR), PCIDE_REG(NSECTOR), PCIDE_REG(SECTOR),
-    PCIDE_REG(LCYL), PCIDE_REG(HCYL), PCIDE_REG(CURRENT), PCIDE_REG(STATUS),
-    PCIDE_REG(CMD)
+    IDE_OFF_W(DATA), IDE_OFF_B(ERROR), IDE_OFF_B(NSECTOR), IDE_OFF_B(SECTOR),
+    IDE_OFF_B(LCYL), IDE_OFF_B(HCYL), 6 /*IDE_OFF_B(CURRENT)*/, IDE_OFF_B(STATUS),
+    518/*IDE_OFF(CMD)*/
 };
 
-static int q40ide_default_irq(q40ide_ioreg_t base)
+static int q40ide_default_irq(ide_ioreg_t base)
 {
-           switch (base) { 
+           switch (base) {
 	            case 0x1f0: return 14;
 		    case 0x170: return 15;
 		    case 0x1e8: return 11;
@@ -67,14 +65,58 @@ 
 }
 
 
+/*
+ * This is very similar to ide_setup_ports except that addresses
+ * are pretranslated for q40 ISA access
+ */
+void q40_ide_setup_ports ( hw_regs_t *hw,
+			ide_ioreg_t base, int *offsets,
+			ide_ioreg_t ctrl, ide_ioreg_t intr,
+			ide_ack_intr_t *ack_intr,
+/*
+ *			ide_io_ops_t *iops,
+ */
+			int irq)
+{
+	int i;
 
-    /*
-     *  Probe for Q40 IDE interfaces
-     */
+	for (i = 0; i < IDE_NR_PORTS; i++) {
+		/* BIG FAT WARNING: 
+		   assumption: only DATA port is ever used in 16 bit mode */
+		if ( i==0 )
+			hw->io_ports[i] = Q40_ISA_IO_W(base + offsets[i]);
+		else
+			hw->io_ports[i] = Q40_ISA_IO_B(base + offsets[i]);
+	}
+	
+	hw->irq = irq;
+	hw->dma = NO_DMA;
+	hw->ack_intr = ack_intr;
+/*
+ *	hw->iops = iops;
+ */
+}
+
+
+
+/* 
+ * the static array is needed to have the name reported in /proc/ioports,
+ * hwif->name unfortunately isnĀ“t available yet
+ */
+static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
+	"ide0", "ide1"
+};
+
+/*
+ *  Probe for Q40 IDE interfaces
+ */
 
 void q40ide_init(void)
 {
     int i;
+    ide_hwif_t *hwif;
+    int index;
+    const char *name;
 
     if (!MACH_IS_Q40)
       return ;
@@ -82,12 +124,27 @@ 
     for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
 	hw_regs_t hw;
 
-	ide_setup_ports(&hw,(ide_ioreg_t) pcide_bases[i], (int *)pcide_offsets, 
-			pcide_bases[i]+0x206, 
-			0, NULL,
-//			pcide_iops,
+	name = q40_ide_names[i];
+	if (!request_region(pcide_bases[i], 8, name)) {
+		printk("could not reserve ports %lx-%lx for %s\n",
+		       pcide_bases[i],pcide_bases[i]+8,name);
+		continue;
+	}
+	if (!request_region(pcide_bases[i]+0x206, 1, name)) {
+		printk("could not reserve port %lx for %s\n",
+		       pcide_bases[i]+0x206,name);
+		release_region(pcide_bases[i], 8);
+		continue;
+	}
+	q40_ide_setup_ports(&hw, (ide_ioreg_t)pcide_bases[i],
+			(int *)pcide_offsets,
+			(ide_ioreg_t)pcide_bases[i]+0x206, 0, NULL,
+//			m68kide_iops,
 			q40ide_default_irq(pcide_bases[i]));
-	ide_register_hw(&hw, NULL);
+	index = ide_register_hw(&hw, &hwif);
+	// **FIXME**
+	if (index != -1)
+		hwif->mmio = 2;
     }
 }
 
--- linux-2.4.21-pre7/include/asm-m68k/hdreg.h	Fri Dec 20 13:21:32 2002
+++ linux-m68k-2.4.21-pre7/include/asm-m68k/hdreg.h	Sun Mar 30 22:22:40 2003
@@ -7,8 +7,6 @@ 
 #ifndef _M68K_HDREG_H
 #define _M68K_HDREG_H
 
-typedef unsigned int   q40ide_ioreg_t;
-typedef unsigned char * ide_ioreg_t;
-//typedef unsigned long ide_ioreg_t;
+typedef unsigned long ide_ioreg_t;
 
 #endif /* _M68K_HDREG_H */
--- linux-2.4.21-pre7/include/asm-m68k/ide.h	Fri Dec 20 13:21:32 2002
+++ linux-m68k-2.4.21-pre7/include/asm-m68k/ide.h	Sun Mar 30 22:22:40 2003
@@ -50,9 +50,6 @@ 
 #define MAX_HWIFS	4	/* same as the other archs */
 #endif
 
-/*
- * FIXME: IOPS struct calls needed for taskfile.
- */
 
 static __inline__ int ide_default_irq(ide_ioreg_t base)
 {
@@ -69,7 +66,9 @@ 
  * Set up a hw structure for a specified data port, control port and IRQ.
  * This should follow whatever the default interface uses.
  */
-static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+static __inline__ void ide_init_hwif_ports(hw_regs_t *hw,
+					   ide_ioreg_t data_port,
+					   ide_ioreg_t ctrl_port, int *irq)
 {
 	if (data_port || ctrl_port)
 		printk("ide_init_hwif_ports: must not be called\n");
@@ -83,170 +82,94 @@ 
 {
 }
 
-static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-			unsigned long flags, const char *device, void *dev_id)
-{
-#ifdef CONFIG_AMIGA
-	if (MACH_IS_AMIGA)
-		return request_irq(irq, handler, 0, device, dev_id);
-#endif /* CONFIG_AMIGA */
-#ifdef CONFIG_Q40
-	if (MACH_IS_Q40)
-	  	return request_irq(irq, handler, 0, device, dev_id);
-#endif /* CONFIG_Q40*/
-#ifdef CONFIG_MAC
-	if (MACH_IS_MAC)
-		return request_irq(irq, handler, 0, device, dev_id);
-#endif /* CONFIG_MAC */
-	return 0;
-}
-
-static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
-{
-#ifdef CONFIG_AMIGA
-	if (MACH_IS_AMIGA)
-		free_irq(irq, dev_id);
-#endif /* CONFIG_AMIGA */
-#ifdef CONFIG_Q40
-	if (MACH_IS_Q40)
-	  	free_irq(irq, dev_id);
-#endif /* CONFIG_Q40*/
-#ifdef CONFIG_MAC
-	if (MACH_IS_MAC)
-		free_irq(irq, dev_id);
-#endif /* CONFIG_MAC */
-}
-
 /*
- * We should really implement those some day.
- */
-static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent)
-{
-	return 0;
-}
-
-static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name)
-{
-#ifdef CONFIG_Q40
-        if (MACH_IS_Q40)
-            request_region((q40ide_ioreg_t)from,extent,name);
-#endif
-}
-
-static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent)
-{
-#ifdef CONFIG_Q40
-        if (MACH_IS_Q40)
-            release_region((q40ide_ioreg_t)from,extent);
-#endif
-}
-
-#undef SUPPORT_SLOW_DATA_PORTS
-#define SUPPORT_SLOW_DATA_PORTS 0
-
-#undef SUPPORT_VLB_SYNC
-#define SUPPORT_VLB_SYNC 0
-
-/* this definition is used only on startup .. */
-#undef HD_DATA
-#define HD_DATA NULL
-
-
-/*
- * get rid of defs from io.h
- * ide still has some private and conflicting versions
+ * Get rid of defs from io.h - ide has its private and conflicting versions
+ * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we
+ * always use the `raw' MMIO versions
  */
+#undef inb
+#undef inw
 #undef insw
+#undef inl
 #undef insl
+#undef outb
+#undef outw
 #undef outsw
+#undef outl
 #undef outsl
-
-
-/*
- * define IO method and translation,
- * so far only Q40 has ide-if on ISA
- */
-#ifndef CONFIG_Q40
-
-#define ADDR_TRANS_B(_addr_) (_addr_)
-#define ADDR_TRANS_W(_addr_) (_addr_)
-#define ADDR_TRANS_L(_addr_) (_addr_)
-
-#else
-
-#define ADDR_TRANS_B(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_B(_addr_)) : (_addr_))
-#define ADDR_TRANS_W(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_W(_addr_)) : (_addr_))
-#define ADDR_TRANS_L(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_L(_addr_)) : (_addr_))
-#endif
-
-#define HAVE_ARCH_OUT_BYTE 1
-
-#define OUT_BYTE(v,p)	out_8(ADDR_TRANS_B((p)), (v))
-#define OUT_WORD(v,p)	out_be16(ADDR_TRANS_W((p)), (v))
-#define OUT_LONG(v,p)	out_be32(ADDR_TRANS_L((p)), (v))
-
-#define HAVE_ARCH_IN_BYTE 1
-
-#define IN_BYTE(p)	in_8(ADDR_TRANS_B((p)))
-#define IN_WORD(p)	in_be16(ADDR_TRANS_W((p)))
-#define IN_LONG(p)	in_be32(ADDR_TRANS_L((p)))
-
-#define insw(port, buf, nr) raw_insw(ADDR_TRANS_W(port), buf, nr)
-#define outsw(port, buf, nr) raw_outsw(ADDR_TRANS_W(port), buf, nr)
-
-#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
-#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
-
-
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+
+#define inb				in_8
+#define inw				in_be16
+#define insw(port, addr, n)		raw_insw((u16 *)port, addr, n)
+#define inl				in_be32
+#define insl(port, addr, n)		raw_insl((u32 *)port, addr, n)
+#define outb(val, port)			out_8(port, val)
+#define outw(val, port)			out_be16(port, val)
+#define outsw(port, addr, n)		raw_outsw((u16 *)port, addr, n)
+#define outl(val, port)			out_be32(port, val)
+#define outsl(port, addr, n)		raw_outsl((u32 *)port, addr, n)
+#define readb				in_8
+#define readw				in_be16
+#define __ide_mm_insw(port, addr, n)	raw_insw((u16 *)port, addr, n)
+#define readl				in_be32
+#define __ide_mm_insl(port, addr, n)	raw_insl((u32 *)port, addr, n)
+#define writeb(val, port)		out_8(port, val)
+#define writew(val, port)		out_be16(port, val)
+#define __ide_mm_outsw(port, addr, n)	raw_outsw((u16 *)port, addr, n)
+#define writel(val, port)		out_be32(port, val)
+#define __ide_mm_outsl(port, addr, n)	raw_outsl((u32 *)port, addr, n)
 #if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
-
-#define insl_swapw(data_reg, buffer, wcount) \
-    insw_swapw(data_reg, buffer, (wcount)<<1)
-#define outsl_swapw(data_reg, buffer, wcount) \
-    outsw_swapw(data_reg, buffer, (wcount)<<1)
-
-#define insw_swapw(port, buf, nr) raw_insw_swapw(ADDR_TRANS_W(port), buf, nr)
-#define outsw_swapw(port, buf, nr) raw_outsw_swapw(ADDR_TRANS_W(port),buf,nr)
-
-#endif /* CONFIG_ATARI || CONFIG_Q40 */
+#define insw_swapw(port, addr, n)	raw_insw_swapw((u16 *)port, addr, n)
+#define outsw_swapw(port, addr, n)	raw_outsw_swapw((u16 *)port, addr, n)
+#endif
 
 
-/* Q40 and Atari have byteswapped IDE bus and since many interesting
+/* Q40 and Atari have byteswapped IDE busses and since many interesting
  * values in the identification string are text, chars and words they
- * happened to be almost correct without swapping.. However *_capacity 
+ * happened to be almost correct without swapping.. However *_capacity
  * is needed for drives over 8 GB. RZ */
 #if defined(CONFIG_Q40) || defined(CONFIG_ATARI)
 #define M68K_IDE_SWAPW  (MACH_IS_Q40 || MACH_IS_ATARI)
 #endif
 
-#ifdef CONFIG_ATARI
-#define IDE_ARCH_LOCK 1
+#ifdef CONFIG_BLK_DEV_FALCON_IDE
+#define IDE_ARCH_LOCK
+
+extern int falconide_intr_lock;
 
-static __inline__ void ide_release_lock (int *ide_lock)
+static __inline__ void ide_release_lock(void)
 {
 	if (MACH_IS_ATARI) {
-		if (*ide_lock == 0) {
+		if (falconide_intr_lock == 0) {
 			printk("ide_release_lock: bug\n");
 			return;
 		}
-		*ide_lock = 0;
+		falconide_intr_lock = 0;
 		stdma_release();
 	}
 }
 
-static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
+static __inline__ void ide_get_lock(void (*handler)(int, void *, struct pt_regs *), void *data)
 {
 	if (MACH_IS_ATARI) {
-		if (*ide_lock == 0) {
+		if (falconide_intr_lock == 0) {
 			if (in_interrupt() > 0)
 				panic( "Falcon IDE hasn't ST-DMA lock in interrupt" );
 			stdma_lock(handler, data);
-			*ide_lock = 1;
+			falconide_intr_lock = 1;
 		}
 	}
 }
-#endif /* CONFIG_ATARI */
+#endif /* CONFIG_BLK_DEV_FALCON_IDE */
 
-#endif /* __KERNEL__ */
+#define IDE_ARCH_ACK_INTR
+#define ide_ack_intr(hwif)	((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
 
+#endif /* __KERNEL__ */
 #endif /* _M68K_IDE_H */