Resent-Date: Mon, 18 Jan 1999 10:10:13 +0100 (MET) Date: Mon, 18 Jan 1999 10:11:52 +0100 (CET) From: "Christian T. Steigies" Reply-To: "Christian T. Steigies" To: linux-m68k Subject: buddha/catweasel for 2.0.36 Resent-From: linux-m68k@phil.uni-sb.de Hi, this is the catweasel patch for 2.0.36-pre2. Can someone with A4000/A1200 IDE please check that this doesnt break anything for him? It would be perfect, if he could test with A4000/A1200 IDE _and_ with buddha also... You can turn on full warning messages by uncommenting AMIGA_BUDDHA_DEBUG, I think the messages are wasting too much kernel memory if they are included in every kernel? This is working for my on A2000 with Catweasel and one IDE disk connected. It should support all three interfaces now, but I did not test with more than one disk yet. Ciao, Christian. --- drivers/block/ide.c.orig Tue Dec 1 17:32:35 1998 +++ drivers/block/ide.c Sun Jan 17 22:07:13 1999 @@ -854,11 +854,11 @@ * individually reset without clobbering other devices on the same interface. * * Unfortunately, the IDE interface does not generate an interrupt to let - * us know when the reset operation has finished, so we must poll for this. - * Equally poor, though, is the fact that this may a very long time to complete, - * (up to 30 seconds worstcase). So, instead of busy-waiting here for it, - * we set a timer to poll at 50ms intervals. - */ + * us know when the reset operation has finished, so we must poll for this. + * Equally poor, though, is the fact that this may take a very long time to + * complete, (up to 30 seconds worstcase). So, instead of busy-waiting here + * for it, we set a timer to poll at 50ms intervals. + */ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi) { unsigned int unit; @@ -3845,9 +3845,16 @@ #endif /* CONFIG_PCI */ #ifdef CONFIG_AMIGA +/* #define AMIGA_BUDDHA_DEBUG */ static void ide_probe_amiga (void) { ide_hwif_t *hwif = &ide_hwifs[0]; + int i, key; + const struct ConfigDev *cd; + static u_long buddha_board = 0; + static int buddha_num_hwifs = 0; + static int amiga_num_hwifs = 0; +#include "buddha.h" if (!MACH_IS_AMIGA) return; @@ -3858,30 +3865,113 @@ if (AMIGAHW_PRESENT(A4000_IDE)) { hwif->io_base = (unsigned char *)ZTWO_VADDR(HD_BASE_A4000); hwif->hd_regs.hd_irq = (unsigned char *)ZTWO_VADDR(HD_A4000_IRQ); + amiga_num_hwifs++; printk("Gayle IDE interface (A4000 style)\n"); } else if (AMIGAHW_PRESENT(A1200_IDE)) { hwif->io_base = (unsigned char *)ZTWO_VADDR(HD_BASE_A1200); hwif->hd_regs.hd_irq = (unsigned char *)ZTWO_VADDR(HD_A1200_IRQ); + amiga_num_hwifs++; printk("Gayle IDE interface (A1200 style)\n"); - } else /* Not A4000 nor A1200, - doesn't have a supported IDE controller */ - { - hwif->noprobe = 1; + } + if (amiga_num_hwifs > 0) { /* we can have max one gayle interface */ + /* Now set the hd_regs struct */ + hwif->hd_regs.hd_error = hwif->io_base + AMI_HD_ERROR; + hwif->hd_regs.hd_nsector = hwif->io_base + AMI_HD_NSECTOR; + hwif->hd_regs.hd_sector = hwif->io_base + AMI_HD_SECTOR; + hwif->hd_regs.hd_lcyl = hwif->io_base + AMI_HD_LCYL; + hwif->hd_regs.hd_hcyl = hwif->io_base + AMI_HD_HCYL; + hwif->hd_regs.hd_select = hwif->io_base + AMI_HD_SELECT; + hwif->hd_regs.hd_status = hwif->io_base + AMI_HD_STATUS; + hwif->ctl_port = hwif->io_base + AMI_HD_CMD; + + /* Disable interrupt for probing */ + disable_irq(hwif->irq); + + hwif++; /* next interface, please */ + + if ( (amiga_num_hwifs + 1) > MAX_HWIFS) { + /* MAX_HWIFS must be >1 for use with buddha/catweasel */ +#ifdef AMIGA_BUDDHA_DEBUG + printk("WARNING: this kernel can handle only %d IDE interfaces!\n", MAX_HWIFS); + printk(" Edit include/asm-m68k/ide.h if you want to use more.\n"); +#endif return; } + } /* Maybe we have a Buddha or Catweasel controller? */ + if ((key = zorro_find(MANUF_INDIVIDUAL_COMP, PROD_BUDDHA, 0, 0))) { + buddha_num_hwifs = BUDDHA_NUM_HWIFS; + printk("Buddha IDE interface\n"); + } else if ((key = zorro_find(MANUF_INDIVIDUAL_COMP, PROD_CATWEASEL, 0, 0))) { + buddha_num_hwifs = CATWEASEL_NUM_HWIFS; + printk("Catweasel IDE interface\n"); + } + if ( (amiga_num_hwifs + buddha_num_hwifs) > MAX_HWIFS) { + /* check if MAX_HWIFS is large enough for gayle and buddha/catweasel */ +#ifdef AMIGA_BUDDHA_DEBUG + printk("WARNING: this kernel can handle only %d IDE interfaces,\n", MAX_HWIFS); + printk(" this machine seems to have %d!\n", (amiga_num_hwifs + buddha_num_hwifs) ); + printk(" Edit include/asm-m68k/ide.h if you want to use them all (now using only %d).\n", amiga_num_hwifs); +#endif + return; + } /* this is very paranoid, too paranoid? */ + if (key) { + cd = zorro_get_board(key); + buddha_board = (u_long)cd->cd_BoardAddr; + if (buddha_board) { + buddha_board = ZTWO_VADDR(buddha_board); + /* write to BUDDHA_IRQ_MR to enable the board IRQ */ + *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0; + zorro_config_board(key, 0); + } else { /* can this happen ? */ + buddha_num_hwifs = 0; + } + } else { /* no buddha or catweasel present */ + buddha_num_hwifs = 0; + } + + if (buddha_num_hwifs > 0) { + /* we have two or three more interfaces, now setup ide_hwifs */ + for (i = 1; i <= buddha_num_hwifs; i++) { + switch (i) { + case 1: + hwif->io_base = (unsigned char *)(buddha_board + BUDDHA_BASE1); + hwif->hd_regs.hd_irq = (unsigned char *)(buddha_board + BUDDHA_IRQ1); + break; + case 2: + hwif->io_base = (unsigned char *)(buddha_board + BUDDHA_BASE2); + hwif->hd_regs.hd_irq = (unsigned char *)(buddha_board + BUDDHA_IRQ2); + break; + case 3: + hwif->io_base = (unsigned char *)(buddha_board + BUDDHA_BASE3); + hwif->hd_regs.hd_irq = (unsigned char *)(buddha_board + BUDDHA_IRQ3); + break; + default: + return; /* this can not happen */ + } + hwif->hd_regs.hd_error = hwif->io_base + BUDDHA_ERROR; + hwif->hd_regs.hd_nsector = hwif->io_base + BUDDHA_NSECTOR; + hwif->hd_regs.hd_sector = hwif->io_base + BUDDHA_SECTOR; + hwif->hd_regs.hd_lcyl = hwif->io_base + BUDDHA_LCYL; + hwif->hd_regs.hd_hcyl = hwif->io_base + BUDDHA_HCYL; + hwif->hd_regs.hd_select = hwif->io_base + BUDDHA_SELECT; + hwif->hd_regs.hd_status = hwif->io_base + BUDDHA_STATUS; + hwif->ctl_port = hwif->io_base + BUDDHA_CONTROL; - /* Now set the hd_regs struct */ - hwif->hd_regs.hd_error = hwif->io_base + AMI_HD_ERROR; - hwif->hd_regs.hd_nsector = hwif->io_base + AMI_HD_NSECTOR; - hwif->hd_regs.hd_sector = hwif->io_base + AMI_HD_SECTOR; - hwif->hd_regs.hd_lcyl = hwif->io_base + AMI_HD_LCYL; - hwif->hd_regs.hd_hcyl = hwif->io_base + AMI_HD_HCYL; - hwif->hd_regs.hd_select = hwif->io_base + AMI_HD_SELECT; - hwif->hd_regs.hd_status = hwif->io_base + AMI_HD_STATUS; - hwif->ctl_port = hwif->io_base + AMI_HD_CMD; + /* Disable interrupt for probing */ + disable_irq(hwif->irq); - /* Disable interrupt for probing */ - disable_irq(hwif->irq); + hwif++; /* next interface, please */ + } + } + if ( ( amiga_num_hwifs + buddha_num_hwifs ) < MAX_HWIFS ) { + /* the kernel could cope with more interfaces, now set the remaining to noprobe */ + int i; + + for (i = (amiga_num_hwifs + buddha_num_hwifs); i < MAX_HWIFS; i++) { + hwif->noprobe = 1; + hwif++; /* next interface, please */ + } + } } #endif /* CONFIG_AMIGA */ --- drivers/block/buddha.h.orig Sun Jan 10 19:35:31 1999 +++ drivers/block/buddha.h Tue Jan 12 06:08:26 1999 @@ -0,0 +1,71 @@ +/* This file as well as the changes in ide.c are based on + * linux/drivers/block/buddha.c from linux-2.1.131 + * + * - tested on A2000, currently only one controller is working + * 19-01-1999 CTS + * + * + * linux/drivers/block/buddha.c -- Amiga Buddha and Catweasel IDE Driver + * + * Copyright (C) 1997 by Geert Uytterhoeven + * + * This driver was written by based on the specifications in README.buddha. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * TODO: + * - test it :-) + * - tune the timings using the speed-register + */ + +#ifndef _BUDDHA_H +#define _BUDDHA_H + + + /* + * The Buddha has 2 IDE interfaces, the Catweasel has 3 + */ + +#define BUDDHA_NUM_HWIFS 2 +#define CATWEASEL_NUM_HWIFS 3 + + + /* + * Bases of the IDE interfaces (relative to the board address) + */ + +#define BUDDHA_BASE1 0x800 +#define BUDDHA_BASE2 0xa00 +#define BUDDHA_BASE3 0xc00 + + + /* + * Offsets from one of the above bases + */ + +#define BUDDHA_DATA 0x00 +#define BUDDHA_ERROR 0x06 /* see err-bits */ +#define BUDDHA_NSECTOR 0x0a /* nr of sectors to read/write */ +#define BUDDHA_SECTOR 0x0e /* starting sector */ +#define BUDDHA_LCYL 0x12 /* starting cylinder */ +#define BUDDHA_HCYL 0x16 /* high byte of starting cyl */ +#define BUDDHA_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */ +#define BUDDHA_STATUS 0x1e /* see status-bits */ +#define BUDDHA_CONTROL 0x11a + + + /* + * Other registers + */ + +#define BUDDHA_IRQ1 0xf00 /* MSB = 1, Harddisk is source of */ +#define BUDDHA_IRQ2 0xf40 /* interrupt */ +#define BUDDHA_IRQ3 0xf80 + + +#define BUDDHA_IRQ_MR 0xfc0 /* master interrupt enable */ + + +#endif /* _BUDDHA_H */ --- include/asm-m68k/ide.h.orig Sun Jan 10 14:23:58 1999 +++ include/asm-m68k/ide.h Tue Jan 12 05:52:56 1999 @@ -26,7 +26,11 @@ #define IDE_MEM_MAPPED_IO #ifndef MAX_HWIFS +#ifdef CONFIG_AMIGA +#define MAX_HWIFS 4 +#else #define MAX_HWIFS 1 +#endif #endif #undef SUPPORT_VLB_SYNC