diff -urN linux-2.4.25-vrs2-orig/drivers/ide/arm/Makefile linux-2.4.25-vrs2/drivers/ide/arm/Makefile --- linux-2.4.25-vrs2-orig/drivers/ide/arm/Makefile 2004-03-08 11:32:09.000000000 +0000 +++ linux-2.4.25-vrs2/drivers/ide/arm/Makefile 2004-04-10 17:59:11.000000000 +0100 @@ -5,7 +5,7 @@ obj-m := obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o -obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o +obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o rapide_io_asm.o obj-$(CONFIG_BLK_DEV_IDE_RISCSTATION) += rstation-ide.o EXTRA_CFLAGS := -I../ diff -urN linux-2.4.25-vrs2-orig/drivers/ide/arm/rapide.c linux-2.4.25-vrs2/drivers/ide/arm/rapide.c --- linux-2.4.25-vrs2-orig/drivers/ide/arm/rapide.c 2003-06-13 15:51:33.000000000 +0100 +++ linux-2.4.25-vrs2/drivers/ide/arm/rapide.c 2004-04-10 22:29:20.000000000 +0100 @@ -1,11 +1,11 @@ /* * linux/drivers/ide/arm/rapide.c * - * Copyright (c) 1996-1998 Russell King. + * Copyright (c) 2004 Peter Naulls * - * Changelog: - * 08-06-1996 RMK Created - * 13-04-1998 RMK Added manufacturer and product IDs + * Based loosely upon ARM Linux ICS IDE driver by Russell King and NetBSD RapIDE + * driver by Mark Brinicombe, and information from the RISC OS sources + * provided by Chris Honey */ #include @@ -17,78 +17,273 @@ #include -static card_ids __init rapide_cids[] = { - { MANU_YELLOWSTONE, PROD_YELLOWSTONE_RAPIDE32 }, - { 0xffff, 0xffff } +/* IDE drive registers */ + +#define PRIMARY_DRIVE_REGISTERS_OFFSET (0x400080 >> 2) +#define PRIMARY_AUX_REGISTER_OFFSET (0x400298 >> 2) +#define PRIMARY_DATA_REGISTER_OFFSET (0x600080 >> 2) + +#define SECONDARY_DRIVE_REGISTERS_OFFSET (0x400000 >> 2) +#define SECONDARY_AUX_REGISTER_OFFSET (0x400218 >> 2) +#define SECONDARY_DATA_REGISTER_OFFSET (0x600000 >> 2) + +#define CONTROL_REGISTERS_OFFSET (0x200000 >> 2) + + +#define IRQ_MASK_REGISTER_OFFSET 0 +#define IRQ_STATUS_REGISTER_OFFSET 0 +#define IRQ_REQUEST_REGISTER_OFFSET 1 + +#define PRIMARY_IRQ_MASK 0x01 +#define SECONDARY_IRQ_MASK 0x02 +#define IRQ_MASK (PRIMARY_IRQ_MASK | SECONDARY_IRQ_MASK) + + + +struct cardinfo { + unsigned int primary; + unsigned int aux; + unsigned int data; + unsigned int mask; }; -static struct expansion_card *ec[MAX_ECARDS]; -static int result[MAX_ECARDS]; -static inline int rapide_register(struct expansion_card *ec) +static struct cardinfo __initdata rapide_regs[] = { + { PRIMARY_DRIVE_REGISTERS_OFFSET, PRIMARY_AUX_REGISTER_OFFSET, + PRIMARY_DATA_REGISTER_OFFSET, PRIMARY_IRQ_MASK }, + { SECONDARY_DRIVE_REGISTERS_OFFSET, SECONDARY_AUX_REGISTER_OFFSET, + SECONDARY_DATA_REGISTER_OFFSET, SECONDARY_IRQ_MASK } +}; + + +struct rapide_card { + ide_hwif_t *hwif[2]; + int channel; + int enabled; + unsigned long base; + unsigned long control; + unsigned long data[2]; +}; + + +extern void rapide_bs_rm_4(char *data, char *buffer, u32 wcount); +extern void rapide_bs_wm_4(char *data, char *buffer, u32 wcount); + + +void rapide_input_data (ide_drive_t *drive, void *buffer, u32 wcount) { - unsigned long port = ecard_address (ec, ECARD_MEMC, 0); - hw_regs_t hw; + ide_hwif_t *hwif = HWIF(drive); + char *data = (void *)((struct rapide_card *)hwif->hwif_data)->data[hwif->channel]; - int i; + rapide_bs_rm_4(data, buffer, wcount); +} - memset(&hw, 0, sizeof(hw)); - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { - hw.io_ports[i] = (ide_ioreg_t)port; - port += 1 << 4; - } - hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206; - hw.irq = ec->irq; +void rapide_output_data (ide_drive_t *drive, void *buffer, u32 wcount) +{ + ide_hwif_t *hwif = HWIF(drive); + char *data = (void *)((struct rapide_card *)hwif->hwif_data)->data[hwif->channel]; - return ide_register_hw(&hw, NULL); + rapide_bs_wm_4(data, buffer, wcount); } -int __init rapide_init(void) + +static void rapide_maskproc(ide_drive_t *drive, int mask) { - int i; + ide_hwif_t *hwif = HWIF(drive); + struct rapide_card *card = hwif->hwif_data; + unsigned long flags; + + local_irq_save(flags); + + card->channel = hwif->channel; + + if (card->enabled && !mask) { + outb(IRQ_MASK, card->control + IRQ_MASK_REGISTER_OFFSET); + } else { + outb(0, card->control + IRQ_MASK_REGISTER_OFFSET); + } - for (i = 0; i < MAX_ECARDS; i++) - ec[i] = NULL; + local_irq_restore(flags); +} - ecard_startfind(); - for (i = 0; ; i++) { - if ((ec[i] = ecard_find(0, rapide_cids)) == NULL) - break; +static ide_hwif_t *rapide_find_hwif(unsigned long dataport) +{ + ide_hwif_t *hwif; + int index; - ecard_claim(ec[i]); - result[i] = rapide_register(ec[i]); + for (index = 0; index < MAX_HWIFS; ++index) { + hwif = &ide_hwifs[index]; + if (hwif->io_ports[IDE_DATA_OFFSET] == (ide_ioreg_t)dataport) + return hwif; } - for (i = 0; i < MAX_ECARDS; i++) - if (ec[i] && result[i] < 0) { - ecard_release(ec[i]); - ec[i] = NULL; + + for (index = 0; index < MAX_HWIFS; ++index) { + hwif = &ide_hwifs[index]; + if (!hwif->io_ports[IDE_DATA_OFFSET]) + return hwif; } - return 0; + + return NULL; } -#ifdef MODULE -MODULE_LICENSE("GPL"); -int init_module (void) +static inline int rapide_register(struct rapide_card *card, int irq, unsigned long regs, unsigned long control, + ide_hwif_t **hwif_p) { - return rapide_init(); + unsigned long port = card->base; + int ide_reg; + hw_regs_t *hw; + ide_hwif_t *hwif = rapide_find_hwif(regs); + + if (!hwif) return -1; + hw = &hwif->hw; + + memset(hw, 0, sizeof(hw_regs_t)); + + for (ide_reg = IDE_DATA_OFFSET; ide_reg <= IDE_STATUS_OFFSET; ide_reg++) { + hwif->io_ports[ide_reg] = + hw->io_ports[ide_reg] = (ide_ioreg_t)port + regs; + port++; + } + hwif->io_ports[IDE_CONTROL_OFFSET] = + hw->io_ports[IDE_CONTROL_OFFSET] = card->base + control; + hw->dma = NO_DMA; + + hwif->irq = + hw->irq = irq; + + hwif->hwif_data = card; + hwif->channel = card->channel; + hwif->maskproc = rapide_maskproc; + + hwif->noprobe = 0; + hwif->chipset = ide_acorn; + + hwif->ata_input_data = rapide_input_data; + hwif->ata_output_data = rapide_output_data; + + hwif->serialized = 1; + + card->hwif[card->channel] = hwif; + + *hwif_p = hwif; + return 0; + } -void cleanup_module (void) + +static void rapide_irqenable(struct expansion_card *ec, int irqnr) { - int i; + struct rapide_card *card = ec->irq_data; - for (i = 0; i < MAX_ECARDS; i++) - if (ec[i]) { - unsigned long port; - port = ecard_address(ec[i], ECARD_MEMC, 0); + card->enabled = 1; - ide_unregister_port(port, ec[i]->irq, 16); - ecard_release(ec[i]); - ec[i] = NULL; - } + outb(IRQ_MASK, card->control + IRQ_MASK_REGISTER_OFFSET); } -#endif + + +static void rapide_irqdisable(struct expansion_card *ec, int irqnr) +{ + struct rapide_card *card = ec->irq_data; + + card->enabled = 0; + + outb(0, card->control + IRQ_MASK_REGISTER_OFFSET); +} + + +static int rapide_irqpending(struct expansion_card *ec) +{ + struct rapide_card *card = ec->irq_data; + + return inb(card->control + IRQ_REQUEST_REGISTER_OFFSET); +} + + +static const expansioncard_ops_t rapide_ops = { + .irqenable = rapide_irqenable, + .irqdisable = rapide_irqdisable, + .irqpending = rapide_irqpending +}; + + +static int __init rapide_probe(struct expansion_card *ec, const struct ecard_id *id) +{ + int interface; + struct rapide_card *card; + unsigned long base; + + printk("RapIDE: IDE card driver for Yellowstone IDE Podule v2\n"); + + if (!(card = kmalloc(sizeof(struct rapide_card), GFP_KERNEL))) + return -ENOMEM; + + card->base = base = ecard_address(ec, ECARD_EASI, ECARD_SYNC); + card->control = base + CONTROL_REGISTERS_OFFSET; + + ec->ops = &rapide_ops; + ec->irq_data = card; + + /* Enable IRQs */ + outb(~0, card->control + IRQ_MASK_REGISTER_OFFSET); + + for (interface = 0; interface < 2; interface++) { + ide_hwif_t *hwif; + + card->data[interface] = ioaddr(base + rapide_regs[interface].data); + card->channel = interface; + + if (rapide_register(card, ec->irq, rapide_regs[interface].primary, + rapide_regs[interface].aux, &hwif) != -1) { + + printk("RapIDE: interface found for channel %d\n", hwif->channel); + + } + } + return 0; + +} + +static void __devexit rapide_remove(struct expansion_card *ec) { + struct rapide_card *card = ecard_get_drvdata(ec); + + if (card->hwif[0]) + card->hwif[0]->io_ports[IDE_DATA_OFFSET] = 0; + if (card->hwif[1]) + card->hwif[1]->io_ports[IDE_DATA_OFFSET] = 0; + + kfree(card); +} + + +static void rapide_shutdown(struct expansion_card *ec) +{ + struct rapide_card *card = ecard_get_drvdata(ec); + + /* Disable interrupts */ + outb(0, card->control + IRQ_MASK_REGISTER_OFFSET); +} + + +static card_ids __initdata rapide_cids[] = { + { MANU_YELLOWSTONE, PROD_YELLOWSTONE_RAPIDE32 }, + { 0xffff, 0xffff } +}; + + +static struct ecard_driver rapide_driver = { + .probe = rapide_probe, + .remove = __devexit_p(rapide_remove), + .shutdown = rapide_shutdown, + .id_table = rapide_cids, +}; + + +int __init rapide_init(void) +{ + return ecard_register_driver(&rapide_driver); +} + diff -urN linux-2.4.25-vrs2-orig/drivers/ide/arm/rapide_io_asm.S linux-2.4.25-vrs2/drivers/ide/arm/rapide_io_asm.S --- linux-2.4.25-vrs2-orig/drivers/ide/arm/rapide_io_asm.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.25-vrs2/drivers/ide/arm/rapide_io_asm.S 2004-04-10 22:20:29.000000000 +0100 @@ -0,0 +1,177 @@ +/* + * Copyright (c) 1997 Mark Brinicombe. + * Copyright (c) 1997 Causality Limited. + * All rights reserved. + * + * Ported to ARM Linux by Peter Naulls + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * EASI space I/O functions for Yellowstone RapIDE podule + * + * These are optimised 32 bit transfer routines + */ + +#define __ASSEMBLY__ +#include +#include + + +ENTRY(rapide_bs_rm_4) + cmp r2, #0 + moveq pc, lr + + tst r2, #0x7f + beq rapide_rm_4_m512 + tst r2, #0x07 + beq rapide_rm_4_m32 + + /* xfer 4 bytes at a time */ +rapide_rm_4_loop: + ldr r3, [r0] + str r3, [r1], #4 + subs r2, r2, #1 + bne rapide_rm_4_loop + + mov pc, lr + +rapide_rm_4_m32: + /* xfer 32 bytes at a time */ + stmfd sp!, {r4-r10} + +rapide_rm_4_m32_loop: + ldmia r0, {r3-r10} + stmia r1!, {r3-r10} + subs r2, r2, #8 + bne rapide_rm_4_m32_loop + + ldmfd sp!, {r4-r10} + mov pc, lr + +rapide_rm_4_m512: + /* xfer 512 bytes at a time */ + stmfd sp!, {r4-r12, r14} + +rapide_rm_4_m512_loop: + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 44 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 88 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 132 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 176 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 220 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 264 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 308 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 352 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 396 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 440 */ + ldmia r0, {r3-r12, r14} + stmia r1!, {r3-r12, r14} /* 484 */ + ldmia r0, {r3-r9} + stmia r1!, {r3-r9} /* 512 */ + subs r2, r2, #128 + bne rapide_rm_4_m512_loop + + ldmfd sp!, {r4-r12, pc} + + +ENTRY(rapide_bs_wm_4) + cmp r2, #0 + moveq pc, lr + + tst r2, #0x7f + beq rapide_wm_4_m512 + tst r2, #0x07 + beq rapide_wm_4_m32 + + /* xfer 4 bytes at a time */ +rapide_wm_4_loop: + ldr r3, [r1], #4 + str r3, [r0] + subs r2, r2, #1 + bne rapide_wm_4_loop + + mov pc, lr + +rapide_wm_4_m32: + /* xfer 32 bytes at a time */ + stmfd sp!, {r4-r10} + +rapide_wm_4_m32_loop: + ldmia r1!, {r3-r10} + stmia r0, {r3-r10} + subs r2, r2, #8 + bne rapide_wm_4_m32_loop + + ldmfd sp!, {r4-r10} + mov pc, lr + +rapide_wm_4_m512: + /* xfer 512 bytes at a time */ + stmfd sp!, {r4-r12, r14} + +rapide_wm_4_m512_loop: + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 44 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 88 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 132 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 176 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 220 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 264 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 308 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 352 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 396 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 440 */ + ldmia r1!, {r3-r12, r14} + stmia r0, {r3-r12, r14} /* 484 */ + ldmia r1!, {r3-r9} + stmia r0, {r3-r9} /* 512 */ + subs r2, r2, #128 + bne rapide_wm_4_m512_loop + + ldmfd sp!, {r4-r12, pc} --- linux-2.4.25-vrs2-orig/Documentation/Configure.help 2004-03-08 11:32:04.000000000 +0000 +++ linux-2.4.25-vrs2/Documentation/Configure.help 2004-04-10 23:12:12.000000000 +0100 @@ -1422,7 +1422,8 @@ RapIDE interface support CONFIG_BLK_DEV_IDE_RAPIDE Say Y here if you want to support the Yellowstone RapIDE controller - manufactured for use with Acorn computers. + manufactured for use with Acorn computers. This driver only works + with version 2 cards presently. Other IDE chipset support CONFIG_IDE_CHIPSETS --- linux-2.4.25-vrs2-orig/include/asm-arm/ecard.h 2003-08-25 12:44:43.000000000 +0100 +++ linux-2.4.25-vrs2/include/asm-arm/ecard.h 2004-04-10 20:20:23.000000000 +0100 @@ -9,7 +9,7 @@ * 11-12-1996 RMK Further minor improvements * 12-09-1997 RMK Added interrupt enable/disable for card level * - * Reference: Acorns Risc OS 3 Programmers Reference Manuals. + * Reference: Acorn's RISC OS 3 Programmers Reference Manuals. */ #ifndef __ASM_ECARD_H @@ -74,8 +74,8 @@ #define MANU_EESOX 0x0064 #define PROD_EESOX_SCSI2 0x008c -#define MANU_YELLOWSTONE 0x0096 -#define PROD_YELLOWSTONE_RAPIDE32 0x0120 +#define MANU_YELLOWSTONE 0x0060 +#define PROD_YELLOWSTONE_RAPIDE32 0x0114 #ifdef ECARD_C #define CONST