2 * linux/drivers/block/macide.c -- Macintosh IDE Driver
4 * Copyright (C) 1998 by Michael Schmitz
6 * This driver was written based on information obtained from the MacOS IDE
7 * driver binary by Mikael Forselius
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive for
14 #include <linux/types.h>
16 #include <linux/interrupt.h>
17 #include <linux/blkdev.h>
18 #include <linux/hdreg.h>
19 #include <linux/zorro.h>
20 #include <linux/ide.h>
22 #include <asm/machw.h>
23 #include <asm/macintosh.h>
24 #include <asm/macints.h>
27 * Base of the IDE interface (see ATAManager ROM code)
30 #define MAC_HD_BASE 0x50f1a000
33 * Offsets from the above base (scaling 4)
36 #define MAC_HD_DATA 0x00
37 #define MAC_HD_ERROR 0x04 /* see err-bits */
38 #define MAC_HD_NSECTOR 0x08 /* nr of sectors to read/write */
39 #define MAC_HD_SECTOR 0x0c /* starting sector */
40 #define MAC_HD_LCYL 0x10 /* starting cylinder */
41 #define MAC_HD_HCYL 0x14 /* high byte of starting cyl */
42 #define MAC_HD_SELECT 0x18 /* 101dhhhh , d=drive, hhhh=head */
43 #define MAC_HD_STATUS 0x1c /* see status-bits */
44 #define MAC_HD_CONTROL 0x38 /* control/altstatus */
46 static int macide_offsets
[IDE_NR_PORTS
] = {
47 MAC_HD_DATA
, MAC_HD_ERROR
, MAC_HD_NSECTOR
, MAC_HD_SECTOR
, MAC_HD_LCYL
,
48 MAC_HD_HCYL
, MAC_HD_SELECT
, MAC_HD_STATUS
, MAC_HD_CONTROL
56 * IDE interrupt status register for both (?) hwifs on Quadra
57 * Initial setting: 0xc
59 * Bit 0+1: some interrupt flags
60 * Bit 2+3: some interrupt enable
62 * Bit 5: IDE interrupt flag (any hwif)
63 * Bit 6: maybe IDE interrupt enable (any hwif) ??
64 * Bit 7: Any interrupt condition
66 * Only relevant item: bit 5, to be checked by mac_ack_intr
69 #define MAC_HD_ISR 0x101
72 * IDE interrupt glue - seems to be wired to Nubus, Slot C?
73 * (ROM code disassembly again)
74 * First try: just use Nubus interrupt for Slot C. Have Nubus code call
75 * a wrapper to ide_intr that checks the ISR (see above).
76 * Need to #define IDE_IRQ_NUBUS though.
77 * Alternative method: set a mac_ide_hook function pointer to the wrapper
78 * here and have via_do_nubus call that hook if set.
80 * Quadra needs the hook, Powerbook can use Nubus slot C.
81 * Checking the ISR on Quadra is done by mac_ack_intr (see Amiga code). mac_ide_intr
82 * mac_ide_intr is obsolete except for providing the hwgroup argument.
85 /* The Mac hwif data, for passing hwgroup to ide_intr */
86 static ide_hwif_t
*mac_hwif
= NULL
;
88 /* The function pointer used in the Nubus handler */
89 void (*mac_ide_intr_hook
)(int, void *, struct pt_regs
*) = NULL
;
92 * Only purpose: feeds the hwgroup to the main IDE handler.
93 * Obsolete as soon as Nubus code is fixed WRT pseudo slot C int.
94 * (should be the case on Powerbooks)
95 * Alas, second purpose: feed correct irq to IDE handler (I know,
96 * that's cheating) :-(((
97 * Fix needed for interrupt code: accept Nubus ints in the regular
98 * request_irq code, then register Powerbook IDE as Nubus slot C,
99 * Quadra as slot F (F for fictious).
101 void mac_ide_intr(int irq
, void *dev_id
, struct pt_regs
*regs
)
103 ide_intr(mac_hwif
->irq
, mac_hwif
->hwgroup
, regs
);
107 * Check the interrupt status
109 * Note: In 2.0 kernels, there have been timing problems with the
110 * Powerbook IDE interface (BUSY was asserted too long after the
111 * interrupt triggered). Result: repeated errors, recalibrate etc.
112 * Adding a wait loop to read_intr, write_intr and set_geom_intr
113 * fixed the problem (waits in read/write_intr were present for Amiga
115 * Powerbooks were not tested with 2.1 due to lack of FPU emulation
116 * (thanks Apple for using LC040). If the BUSY problem resurfaces in
117 * 2.1, my best bet would be to add the wait loop right here, afterr
118 * checking the interrupt register.
121 static int mac_ack_intr(ide_hwif_t
*hwif
)
125 ch
= inb(hwif
->io_ports
[IDE_IRQ_OFFSET
]);
132 * Probe for a Macintosh IDE interface
135 void macide_init(void)
141 switch(macintosh_config
->ide_type
) {
146 ide_setup_ports(&hw
, (ide_ioreg_t
)MAC_HD_BASE
, macide_offsets
,
147 0, (ide_ioreg_t
)(MAC_HD_BASE
+MAC_HD_ISR
),
148 mac_ack_intr
, IRQ_MAC_NUBUS
);
149 index
= ide_register_hw(&hw
, &mac_hwif
);
150 mac_ide_intr_hook
= mac_ide_intr
;
154 ide_setup_ports(&hw
, (ide_ioreg_t
)MAC_HD_BASE
, macide_offsets
,
155 0, 0, NULL
, IRQ_MAC_NUBUS
);
156 index
= ide_register_hw(&hw
, &mac_hwif
);
161 if (macintosh_config
->ide_type
== MAC_IDE_QUADRA
)
162 printk("ide%d: Macintosh Quadra IDE interface\n", index
);
164 printk("ide%d: Macintosh Powerbook IDE interface\n", index
);