~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/ide/gayle.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/drivers/ide/gayle.c -- Amiga Gayle IDE Driver
  3  *
  4  *     Created 9 Jul 1997 by Geert Uytterhoeven
  5  *
  6  *  This file is subject to the terms and conditions of the GNU General Public
  7  *  License.  See the file COPYING in the main directory of this archive for
  8  *  more details.
  9  */
 10 
 11 #include <linux/config.h>
 12 #include <linux/types.h>
 13 #include <linux/mm.h>
 14 #include <linux/interrupt.h>
 15 #include <linux/blkdev.h>
 16 #include <linux/hdreg.h>
 17 #include <linux/ide.h>
 18 #include <linux/init.h>
 19 
 20 #include <asm/setup.h>
 21 #include <asm/amigahw.h>
 22 #include <asm/amigaints.h>
 23 #include <asm/amigayle.h>
 24 
 25 
 26     /*
 27      *  Bases of the IDE interfaces
 28      */
 29 
 30 #define GAYLE_BASE_4000 0xdd2020        /* A4000/A4000T */
 31 #define GAYLE_BASE_1200 0xda0000        /* A1200/A600 */
 32 
 33     /*
 34      *  Offsets from one of the above bases
 35      */
 36 
 37 #define GAYLE_DATA      0x00
 38 #define GAYLE_ERROR     0x06            /* see err-bits */
 39 #define GAYLE_NSECTOR   0x0a            /* nr of sectors to read/write */
 40 #define GAYLE_SECTOR    0x0e            /* starting sector */
 41 #define GAYLE_LCYL      0x12            /* starting cylinder */
 42 #define GAYLE_HCYL      0x16            /* high byte of starting cyl */
 43 #define GAYLE_SELECT    0x1a            /* 101dhhhh , d=drive, hhhh=head */
 44 #define GAYLE_STATUS    0x1e            /* see status-bits */
 45 #define GAYLE_CONTROL   0x101a
 46 
 47 static int gayle_offsets[IDE_NR_PORTS] __initdata = {
 48     GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL,
 49     GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, -1, -1
 50 };
 51 
 52 
 53     /*
 54      *  These are at different offsets from the base
 55      */
 56 
 57 #define GAYLE_IRQ_4000  0xdd3020        /* MSB = 1, Harddisk is source of */
 58 #define GAYLE_IRQ_1200  0xda9000        /* interrupt */
 59 
 60 
 61     /*
 62      *  Offset of the secondary port for IDE doublers
 63      *  Note that GAYLE_CONTROL is NOT available then!
 64      */
 65 
 66 #define GAYLE_NEXT_PORT 0x1000
 67 
 68 #ifndef CONFIG_BLK_DEV_IDEDOUBLER
 69 #define GAYLE_NUM_HWIFS         1
 70 #define GAYLE_NUM_PROBE_HWIFS   GAYLE_NUM_HWIFS
 71 #define GAYLE_HAS_CONTROL_REG   1
 72 #define GAYLE_IDEREG_SIZE       0x2000
 73 #else /* CONFIG_BLK_DEV_IDEDOUBLER */
 74 #define GAYLE_NUM_HWIFS         2
 75 #define GAYLE_NUM_PROBE_HWIFS   (ide_doubler ? GAYLE_NUM_HWIFS : \
 76                                                GAYLE_NUM_HWIFS-1)
 77 #define GAYLE_HAS_CONTROL_REG   (!ide_doubler)
 78 #define GAYLE_IDEREG_SIZE       (ide_doubler ? 0x1000 : 0x2000)
 79 int ide_doubler = 0;    /* support IDE doublers? */
 80 #endif /* CONFIG_BLK_DEV_IDEDOUBLER */
 81 
 82 
 83     /*
 84      *  Check and acknowledge the interrupt status
 85      */
 86 
 87 static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
 88 {
 89     unsigned char ch;
 90 
 91     ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
 92     if (!(ch & GAYLE_IRQ_IDE))
 93         return 0;
 94     return 1;
 95 }
 96 
 97 static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
 98 {
 99     unsigned char ch;
100 
101     ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
102     if (!(ch & GAYLE_IRQ_IDE))
103         return 0;
104     (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
105     outb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
106     return 1;
107 }
108 
109     /*
110      *  Probe for a Gayle IDE interface (and optionally for an IDE doubler)
111      */
112 
113 void __init gayle_init(void)
114 {
115     int a4000, i;
116 
117     if (!MACH_IS_AMIGA)
118         return;
119 
120     if (!(a4000 = AMIGAHW_PRESENT(A4000_IDE)) && !AMIGAHW_PRESENT(A1200_IDE))
121         return;
122 
123     for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
124         ide_ioreg_t base, ctrlport, irqport;
125         ide_ack_intr_t *ack_intr;
126         hw_regs_t hw;
127         int index;
128         unsigned long phys_base, res_start, res_n;
129 
130         if (a4000) {
131             phys_base = GAYLE_BASE_4000;
132             irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_4000);
133             ack_intr = gayle_ack_intr_a4000;
134         } else {
135             phys_base = GAYLE_BASE_1200;
136             irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_1200);
137             ack_intr = gayle_ack_intr_a1200;
138         }
139         phys_base += i*GAYLE_NEXT_PORT;
140 
141         res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
142         res_n = GAYLE_IDEREG_SIZE;
143 
144         if (!request_mem_region(res_start, res_n, "IDE"))
145             continue;
146 
147         base = (ide_ioreg_t)ZTWO_VADDR(phys_base);
148         ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
149 
150         ide_setup_ports(&hw, base, gayle_offsets,
151                         ctrlport, irqport, ack_intr, IRQ_AMIGA_PORTS);
152 
153         index = ide_register_hw(&hw, NULL);
154         if (index != -1) {
155             switch (i) {
156                 case 0:
157                     printk("ide%d: Gayle IDE interface (A%d style)\n", index,
158                            a4000 ? 4000 : 1200);
159                     break;
160 #ifdef CONFIG_BLK_DEV_IDEDOUBLER
161                 case 1:
162                     printk("ide%d: IDE doubler\n", index);
163                     break;
164 #endif /* CONFIG_BLK_DEV_IDEDOUBLER */
165             }
166         } else
167             release_mem_region(res_start, res_n);
168 
169 #if 1 /* TESTING */
170         if (i == 1) {
171             volatile u_short *addr = (u_short *)base;
172             u_short data;
173             printk("+++ Probing for IDE doubler... ");
174             *addr = 0xffff;
175             data = *addr;
176             printk("probe returned 0x%02x (PLEASE REPORT THIS!!)\n", data);
177         }
178 #endif /* TESTING */
179     }
180 }
181 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.