From: Linus Torvalds Date: Fri, 23 Nov 2007 20:17:16 +0000 (-0500) Subject: Import 2.1.129pre2 X-Git-Tag: 2.1.129pre2 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=73f97101a59e99a77a4d07506a46d1c92cc0078a;p=history.git Import 2.1.129pre2 --- diff --git a/Documentation/Configure.help b/Documentation/Configure.help index abec1923c375..bfff09d86f87 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -3937,9 +3937,8 @@ CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS this feature, enter 0 or 1 here (it doesn't matter which). The default value is 8 and should be supported by most hard disks. - This option has no effect for adapters with NVRAM, since the driver - will get this information from the user set-up. It also can be - overridden using a boot setup option, as follows (example): + This value can be overridden from the boot command line using the + 'tags' option as follows (example): 'ncr53c8xx=tags:4/t2t3q16/t0u2q10' will set default queue depth to 4, set queue depth to 16 for target 2 and target 3 on controller 0 and set queue depth to 10 for target 0 / lun 2 on controller 1. @@ -3954,12 +3953,10 @@ maximum number of queued commands CONFIG_SCSI_NCR53C8XX_MAX_TAGS This option allows you to specify the maximum number of commands that can be queued to any device, when tagged command queuing is - possible. The default value is 32. Minimum is 2, maximum is 64. For - value less than 32, this option only saves a little memory - (8*7*(32-MAXTAGS) bytes), so using less than 32 isn't worth it. For - value greater than 32, latency on reselection will be increased by 1 - or 2 micro-seconds. - + possible. The default value is 32. Minimum is 2, maximum is 64. + Modern hard disks are able to support 64 tags and even more, but + donnot seem to be faster when more than 32 tags are being used. + So, the normal answer here is to go with the default value 32 unless you are using very large hard disks with large cache (>= 1 MB) that are able to take advantage of more than 32 tagged commands. @@ -9686,7 +9683,7 @@ CONFIG_TT_DMA_EMUL Ariadne support CONFIG_ARIADNE - If you have a VillageTronics Ariadne Ethernet adapter, say Y. + If you have a Village Tronic Ariadne Ethernet adapter, say Y. Otherwise, say N. This driver is also available as a module ( = code which can be @@ -9696,7 +9693,7 @@ CONFIG_ARIADNE Ariadne II support CONFIG_ARIADNE2 - If you have a VillageTronics Ariadne II Ethernet adapter, say Y. + If you have a Village Tronic Ariadne II Ethernet adapter, say Y. Otherwise, say N. This driver is also available as a module ( = code which can be @@ -10272,7 +10269,7 @@ CONFIG_FRAME_POINTER # LocalWords: INSNS Ataris AutoConfig ZORRO OCS AMIFB Agnus Denise ECS CDTV GB # LocalWords: AGA Cybervision CYBER GSP TMS DMI Zorro ACSI ROMs SLM BioNet GVP # LocalWords: PAMsNet TekMagic Cyberstorm MkI CYBERSTORMII MkII BLZ onboard cx -# LocalWords: VillageTronics ATARILANCE RieblCard PAMCard VME MFP sangoma LAPB +# LocalWords: Village Tronic ATARILANCE RieblCard PAMCard VME MFP sangoma LAPB # LocalWords: Rhotron BioData's Multiface AMIGAMOUSE COPCON Amiga's bitplanes # LocalWords: ATARIMOUSE MFPSER SCC's MegaSTE ESCC Atari's GVPIOEXT DMASOUND # LocalWords: fdutils cisco univercd rpcg htm iface lapb LAPBETHER tpqic qic diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 00c1226cd881..dbd6e1942a91 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -526,9 +526,9 @@ __initfunc(static unsigned long calibrate_tsc(void)) /* Now let's take care of CTC channel 2 */ "movb $0xb0, %%al\n\t" /* binary, mode 0, LSB/MSB, ch 2*/ "outb %%al, $0x43\n\t" /* Write to CTC command port */ - "movb $0x0c, %%al\n\t" + "movl %1, %%eax\n\t" "outb %%al, $0x42\n\t" /* LSB of count */ - "movb $0xe9, %%al\n\t" + "shrl $8, %%eax\n\t" "outb %%al, $0x42\n\t" /* MSB of count */ /* Read the TSC; counting has just started */ @@ -562,12 +562,12 @@ __initfunc(static unsigned long calibrate_tsc(void)) * do a real 64-by-64 divide before that time's up. */ "movl %%eax, %%ecx\n\t" "xorl %%eax, %%eax\n\t" - "movl %1, %%edx\n\t" + "movl %2, %%edx\n\t" "divl %%ecx\n\t" /* eax= 2^32 / (1 * TSC counts per microsecond) */ /* Return eax for the use of fast_gettimeoffset */ "movl %%eax, %0\n\t" : "=r" (retval) - : "r" (5 * 1000020/HZ) + : "r" (5 * LATCH), "r" (5 * 1000020/HZ) : /* we clobber: */ "ax", "bx", "cx", "dx", "cc", "memory"); return retval; } diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 990b24b84062..cd98b4513dc6 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -16,6 +16,8 @@ KERNELLOAD =0xc0000000 ifeq ($(shell uname -m),ppc) CHECKS = checks +else +CROSS_COMPILE = ppc-linux-elf- endif ASFLAGS = diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c index ad75383d2071..690173cc9f81 100644 --- a/arch/ppc/amiga/amiints.c +++ b/arch/ppc/amiga/amiints.c @@ -108,6 +108,11 @@ __initfunc(void amiga_init_IRQ(void)) custom.intreq = 0x7fff; #ifdef CONFIG_APUS + /* Clear any inter-CPU interupt requests. Circumvents bug in + Blizzard IPL emulation HW (or so it appears). */ + APUS_WRITE(APUS_INT_LVL, INTLVL_SETRESET | INTLVL_MASK); + + /* Init IPL emulation. */ APUS_WRITE(APUS_REG_INT, REGINT_INTMASTER | REGINT_ENABLEIPL); APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT); APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_IPLMASK); @@ -304,12 +309,14 @@ void amiga_enable_irq(unsigned int irq) } if (irq >= IRQ_AMIGA_CIAB) { + cia_set_irq(&ciab_base, (1 << (irq - IRQ_AMIGA_CIAB))); cia_able_irq(&ciab_base, CIA_ICR_SETCLR | (1 << (irq - IRQ_AMIGA_CIAB))); return; } if (irq >= IRQ_AMIGA_CIAA) { + cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA))); cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | (1 << (irq - IRQ_AMIGA_CIAA))); return; diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c index c7240a65ad84..f79172390af9 100644 --- a/arch/ppc/amiga/config.c +++ b/arch/ppc/amiga/config.c @@ -434,10 +434,6 @@ __initfunc(void config_amiga(void)) */ if (AMIGAHW_PRESENT(MAGIC_REKICK)) *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; - -#ifdef CONFIG_ZORRO - zorro_init(); -#endif } static unsigned short jiffy_ticks; @@ -739,33 +735,32 @@ static void amiga_savekmsg_init(void) savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM); savekmsg->magic1 = SAVEKMSG_MAGIC1; savekmsg->magic2 = SAVEKMSG_MAGIC2; - savekmsg->magicptr = VTOP(savekmsg); + savekmsg->magicptr = virt_to_phys(savekmsg); savekmsg->size = 0; } static void amiga_serial_putc(char c) { - custom.serdat = (unsigned char)c | 0x100; - -#ifdef CONFIG_APUS - /* I'm sure this should not be necessary since the address is - marked non-cachable and coherent. Still, without it the - serial output is not usable. -jskov */ - eieio (); -#endif - - while (!(custom.serdatr & 0x2000)) - ; + custom.serdat = (unsigned char)c | 0x100; + iobarrier (); + while (!(custom.serdatr & 0x2000)) + ; } void amiga_serial_console_write(struct console *co, const char *s, unsigned int count) { - while (count--) { - if (*s == '\n') - amiga_serial_putc('\r'); - amiga_serial_putc(*s++); - } +#if 0 /* def CONFIG_KGDB */ + /* FIXME:APUS GDB doesn't seem to like O-packages before it is + properly connected with the target. */ + __gdb_output_string (s, count); +#else + while (count--) { + if (*s == '\n') + amiga_serial_putc('\r'); + amiga_serial_putc(*s++); + } +#endif } #ifdef CONFIG_SERIAL_CONSOLE diff --git a/arch/ppc/amiga/time.c b/arch/ppc/amiga/time.c index b14a59b53e9a..65f94d778ea5 100644 --- a/arch/ppc/amiga/time.c +++ b/arch/ppc/amiga/time.c @@ -1,3 +1,4 @@ +#include /* CONFIG_HEARTBEAT */ #include #include #include @@ -68,3 +69,24 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon, } +void apus_heartbeat (void) +{ +#ifdef CONFIG_HEARTBEAT + static unsigned cnt = 0, period = 0, dist = 0; + + if (cnt == 0 || cnt == dist) + mach_heartbeat( 1 ); + else if (cnt == 7 || cnt == dist+7) + mach_heartbeat( 0 ); + + if (++cnt > period) { + cnt = 0; + /* The hyperbolic function below modifies the heartbeat period + * length in dependency of the current (5min) load. It goes + * through the points f(0)=126, f(1)=86, f(5)=51, + * f(inf)->30. */ + period = ((672<= 47) && (bus_speed < 53)) { + bus_speed = 50; + freq = 12500000; + } else if ((bus_speed >= 57) && (bus_speed < 63)) { + bus_speed = 60; + freq = 15000000; + } else if ((bus_speed >= 63) && (bus_speed < 69)) { + bus_speed = 66; + freq = 16500000; + } else { + printk ("APUS: Unable to determine bus speed (%d). " + "Defaulting to 50MHz", bus_speed); + bus_speed = 50; + freq = 12500000; + } + + /* Ease diagnostics... */ { - int speed; - switch (freq) - { - case 0: - freq = 15000000; - speed = 60; - break; - - case 1: - freq = 16500000; - speed =66; - break; - } - - /* Use status of left mouse button to select - RAM speed. */ - if (!(ciaa.pra & 0x40)) - { - APUS_WRITE (APUS_REG_WAITSTATE, - REGWAITSTATE_SETRESET - |REGWAITSTATE_PPCR - |REGWAITSTATE_PPCW); - printk (" [RAM R/W waitstate removed. " - "(expecting 60ns RAM).] "); + extern int __map_without_bats; + + printk ("APUS: BATs=%d, BUS=%dMHz, RAM=%dns\n", + (__map_without_bats) ? 0 : 1, + bus_speed, + (__60nsram) ? 60 : 70); + + /* print a bit more if asked politely... */ + if (!(ciaa.pra & 0x40)){ + extern unsigned int bat_addrs[4][3]; + int b; + for (b = 0; b < 4; ++b) { + printk ("APUS: BAT%d ", b); + printk ("%08x-%08x -> %08x\n", + bat_addrs[b][0], + bat_addrs[b][1], + bat_addrs[b][2]); + } } - - printk ("PowerUp Bus Speed: %dMHz\n", speed); } freq *= 60; /* try to make freq/1e6 an integer */ diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 70c570b5fbf4..5b373c876fc3 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -39,6 +39,7 @@ #include #include #include +#include extern void hydra_init(void); extern void w83c553f_init(void); @@ -191,7 +192,15 @@ chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p)) aux_device_present = 0xaa; - ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ +#ifdef CONFIG_BLK_DEV_INITRD + /* this is fine for chrp */ + initrd_below_start_ok = 1; + + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif + ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ printk("Boot arguments: %s\n", cmd_line); @@ -205,7 +214,6 @@ chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p)) /* PCI bridge config space access area - * appears to be not in devtree on longtrail. */ ioremap(GG2_PCI_CONFIG_BASE, 0x80000); - /* * Temporary fixes for PCI devices. * -- Geert @@ -217,10 +225,13 @@ chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p)) * Fix the Super I/O configuration */ sio_init(); - #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif + /* my starmax 6000 needs this but the longtrail shouldn't do it -- Cort */ + if ( !strncmp("MOT", get_property(find_path_device("/"), + "model", NULL),3) ) + *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p); } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c new file mode 100644 index 000000000000..48d8bcb392eb --- /dev/null +++ b/arch/ppc/kernel/feature.c @@ -0,0 +1,249 @@ +/* + * arch/ppc/kernel/feature.c + * + * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FEATURE_REGS 2 +#undef DEBUG_FEATURE + +static u32 feature_bits_pbook[] = { + 0, /* FEATURE_null */ + OH_SCC_RESET, /* FEATURE_Serial_reset */ + OH_SCC_ENABLE, /* FEATURE_Serial_enable */ + OH_SCCA_IO, /* FEATURE_Serial_IO_A */ + OH_SCCB_IO, /* FEATURE_Serial_IO_B */ + OH_FLOPPY_ENABLE, /* FEATURE_SWIM3_enable */ + OH_MESH_ENABLE, /* FEATURE_MESH_enable */ + OH_IDE_ENABLE, /* FEATURE_IDE_enable */ + OH_VIA_ENABLE, /* FEATURE_VIA_enable */ + OH_IDECD_POWER, /* FEATURE_CD_power */ + OH_BAY_RESET, /* FEATURE_Mediabay_reset */ + OH_BAY_ENABLE, /* FEATURE_Mediabay_enable */ + OH_BAY_PCI_ENABLE, /* FEATURE_Mediabay_PCI_enable */ + OH_BAY_IDE_ENABLE, /* FEATURE_Mediabay_IDE_enable */ + OH_BAY_FLOPPY_ENABLE, /* FEATURE_Mediabay_floppy_enable */ + 0, /* FEATURE_BMac_reset */ + 0, /* FEATURE_BMac_IO_enable */ + 0, /* FEATURE_Modem_PowerOn -> guess...*/ + 0 /* FEATURE_Modem_Reset -> guess...*/ +}; + +/* assume these are the same as the ohare until proven otherwise */ +static u32 feature_bits_heathrow[] = { + 0, /* FEATURE_null */ + OH_SCC_RESET, /* FEATURE_Serial_reset */ + OH_SCC_ENABLE, /* FEATURE_Serial_enable */ + OH_SCCA_IO, /* FEATURE_Serial_IO_A */ + OH_SCCB_IO, /* FEATURE_Serial_IO_B */ + OH_FLOPPY_ENABLE, /* FEATURE_SWIM3_enable */ + OH_MESH_ENABLE, /* FEATURE_MESH_enable */ + OH_IDE_ENABLE, /* FEATURE_IDE_enable */ + OH_VIA_ENABLE, /* FEATURE_VIA_enable */ + OH_IDECD_POWER, /* FEATURE_CD_power */ + OH_BAY_RESET, /* FEATURE_Mediabay_reset */ + OH_BAY_ENABLE, /* FEATURE_Mediabay_enable */ + OH_BAY_PCI_ENABLE, /* FEATURE_Mediabay_PCI_enable */ + OH_BAY_IDE_ENABLE, /* FEATURE_Mediabay_IDE_enable */ + OH_BAY_FLOPPY_ENABLE, /* FEATURE_Mediabay_floppy_enable */ + 0x80000000, /* FEATURE_BMac_reset */ + 0x60000000, /* FEATURE_BMac_IO_enable */ + 0x02000000, /* FEATURE_Modem_PowerOn -> guess...*/ + 0x07000000 /* FEATURE_Modem_Reset -> guess...*/ +}; + +/* definition of a feature controller object */ +struct feature_controller +{ + u32* bits; + volatile u32* reg; + struct device_node* device; +}; + +/* static functions */ +static void +feature_add_controller(struct device_node *controller_device, u32* bits); + +static int +feature_lookup_controller(struct device_node *device); + +/* static varialbles */ +static struct feature_controller controllers[MAX_FEATURE_REGS]; +static int controller_count = 0; + + +void +feature_init(void) +{ + struct device_node *np; + + np = find_devices("mac-io"); + while (np != NULL) + { + feature_add_controller(np, feature_bits_heathrow); + np = np->next; + } + if (controller_count == 0) + { + np = find_devices("ohare"); + if (np) + { + if (find_devices("via-pmu") != NULL) + feature_add_controller(np, feature_bits_pbook); + else + /* else not sure; maybe this is a Starmax? */ + feature_add_controller(np, NULL); + } + } + + if (controller_count) + printk(KERN_INFO "Registered %d feature controller(s)\n", controller_count); +} + +static void +feature_add_controller(struct device_node *controller_device, u32* bits) +{ + struct feature_controller* controller; + + if (controller_count >= MAX_FEATURE_REGS) + { + printk(KERN_INFO "Feature controller %s skipped(MAX:%d)\n", + controller_device->full_name, MAX_FEATURE_REGS); + return; + } + controller = &controllers[controller_count]; + + controller->bits = bits; + controller->device = controller_device; + if (controller_device->n_addrs == 0) { + printk(KERN_ERR "No addresses for %s\n", + controller_device->full_name); + return; + } + + controller->reg = (volatile u32 *)ioremap( + controller_device->addrs[0].address + OHARE_FEATURE_REG, 4); + + if (bits == NULL) { + printk(KERN_INFO "Twiddling the magic ohare bits\n"); + out_le32(controller->reg, STARMAX_FEATURES); + return; + } + + controller_count++; +} + +static int +feature_lookup_controller(struct device_node *device) +{ + int i; + + if (device == NULL) + return -EINVAL; + + while(device) + { + for (i=0; iparent; + } + +#ifdef DEBUG_FEATURE + printk("feature: <%s> not found on any controller\n", + device->name); +#endif + + return -ENODEV; +} + +int +feature_set(struct device_node* device, enum system_feature f) +{ + int controller; + unsigned long flags; + + if (f >= FEATURE_last) + return -EINVAL; + + controller = feature_lookup_controller(device); + if (controller < 0) + return controller; + +#ifdef DEBUG_FEATURE + printk("feature: <%s> setting feature %d in controller @0x%x\n", + device->name, (int)f, (unsigned int)controllers[controller].reg); +#endif + + save_flags(flags); + cli(); + st_le32( controllers[controller].reg, + ld_le32(controllers[controller].reg) | + controllers[controller].bits[f]); + restore_flags(flags); + udelay(10); + + return 0; +} + +int +feature_clear(struct device_node* device, enum system_feature f) +{ + int controller; + unsigned long flags; + + if (f >= FEATURE_last) + return -EINVAL; + + controller = feature_lookup_controller(device); + if (controller < 0) + return controller; + +#ifdef DEBUG_FEATURE + printk("feature: <%s> clearing feature %d in controller @0x%x\n", + device->name, (int)f, (unsigned int)controllers[controller].reg); +#endif + + save_flags(flags); + cli(); + st_le32( controllers[controller].reg, + ld_le32(controllers[controller].reg) & + ~(controllers[controller].bits[f])); + restore_flags(flags); + udelay(10); + + return 0; +} + +int +feature_test(struct device_node* device, enum system_feature f) +{ + int controller; + + if (f >= FEATURE_last) + return -EINVAL; + + controller = feature_lookup_controller(device); + if (controller < 0) + return controller; + + return (ld_le32(controllers[controller].reg) & + controllers[controller].bits[f]) != 0; +} + diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index ebbd0f45e4a5..4c528beb88dd 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -1,7 +1,7 @@ /* * arch/ppc/kernel/head.S * - * $Id: head.S,v 1.107 1998/09/25 19:48:52 paulus Exp $ + * $Id: head.S,v 1.111 1998/11/10 01:10:32 paulus Exp $ * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -210,7 +210,8 @@ __start: mr r27,r7 #ifndef CONFIG_8xx bl prom_init - + .globl __secondary_start +__secondary_start: /* * Use the first pair of BAT registers to map the 1st 16MB * of RAM to KERNELBASE. From this point on we can't safely @@ -1395,15 +1396,13 @@ hash_page_out: next_slot: .long 0 -/* - * FPU stuff for the 6xx/7xx follows - * -- Cort - */ load_up_fpu: /* * Disable FP for the task which had the FPU previously, * and save its floating-point registers in its thread_struct. * Enables the FPU for use in the kernel on return. + * On SMP we know the fpu is free, since we give it up every + * switch. -- Cort */ #ifndef CONFIG_APUS lis r6,-KERNELBASE@h @@ -1411,28 +1410,23 @@ load_up_fpu: lis r6,CYBERBASEp@h lwz r6,0(r6) #endif + addis r3,r6,last_task_used_math@ha lwz r4,last_task_used_math@l(r3) mfmsr r5 ori r5,r5,MSR_FP SYNC mtmsr r5 /* enable use of fpu now */ -#ifndef __SMP__ - SYNC - cmpi 0,r4,0 - beq 1f -#else /* * All the saving of last_task_used_math is handled * by a switch_to() call to smp_giveup_fpu() in SMP so * last_task_used_math is not used. - * - * We should never be here on SMP anyway, since the fpu should - * always be on. * -- Cort */ - b 1f -#endif +#ifndef __SMP__ + SYNC + cmpi 0,r4,0 + beq 1f add r4,r4,r6 addi r4,r4,TSS /* want TSS of last_task_used_math */ SAVE_32FPRS(0, r4) @@ -1444,19 +1438,17 @@ load_up_fpu: li r20,MSR_FP|MSR_FE0|MSR_FE1 andc r4,r4,r20 /* disable FP for previous task */ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) - +#endif /* __SMP__ */ 1: ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1 /* enable use of FP after return */ mfspr r5,SPRG3 /* current task's TSS (phys) */ lfd fr0,TSS_FPSCR-4(r5) mtfsf 0xff,fr0 REST_32FPRS(0, r5) -/* - * on SMP we don't really use last_task_used_math but set it - * here anyway to avoid the ifdef's -- Cort - */ subi r4,r5,TSS sub r4,r4,r6 +#ifndef __SMP__ stw r4,last_task_used_math@l(r3) +#endif /* __SMP__ */ /* restore registers and return */ lwz r3,_CCR(r21) lwz r4,_LINK(r21) @@ -1516,8 +1508,10 @@ giveup_fpu: cmpi 0,r4,0 beqlr- /* if no previous owner, done */ addi r4,r4,TSS /* want TSS of last_task_used_math */ +#ifndef __SMP__ li r5,0 stw r5,last_task_used_math@l(r3) +#endif /* __SMP__ */ SAVE_32FPRS(0, r4) mffs fr0 stfd fr0,TSS_FPSCR-4(r4) @@ -1628,14 +1622,27 @@ start_here: 5: mtspr HID0,r11 /* superscalar exec & br history tbl */ 4: #endif /* CONFIG_8xx */ +#ifdef __SMP__ + /* if we're the second cpu stack and r2 are different + * and we want to not clear the bss -- Cort */ + lis r5,first_cpu_booted@h + ori r5,r5,first_cpu_booted@l + lwz r5,0(r5) + cmpi 0,r5,0 + beq 99f + + /* get current */ + lis r2,current_set@h + ori r2,r2,current_set@l + addi r2,r2,4 + lwz r2,0(r2) + + b 10f +99: +#endif /* __SMP__ */ /* ptr to current */ lis r2,init_task_union@h ori r2,r2,init_task_union@l - /* stack */ - addi r1,r2,TASK_UNION_SIZE - li r0,0 - stwu r0,-STACK_FRAME_OVERHEAD(r1) - /* Clear out the BSS */ lis r11,_end@ha addi r11,r11,_end@l @@ -1651,6 +1658,15 @@ start_here: 3: stwu r0,4(r8) bdnz 3b 2: +#ifdef __SMP__ +10: +#endif /* __SMP__ */ + + /* stack */ + addi r1,r2,TASK_UNION_SIZE + li r0,0 + stwu r0,-STACK_FRAME_OVERHEAD(r1) + /* * Decide what sort of machine this is and initialize the MMU. */ @@ -1999,6 +2015,8 @@ int_return: beq+ 1f addi r3,r1,STACK_FRAME_OVERHEAD bl do_IRQ + .globl lost_irq_ret +lost_irq_ret: b 3b 1: lis r4,bh_mask@ha lwz r4,bh_mask@l(r4) @@ -2007,6 +2025,8 @@ int_return: and. r4,r4,r5 beq+ 2f bl do_bottom_half + .globl do_bottom_half_ret +do_bottom_half_ret: SYNC mtmsr r30 /* disable interrupts again */ SYNC @@ -2024,6 +2044,8 @@ int_return: li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD bl do_signal + .globl do_signal_ret +do_signal_ret: b 0b 8: addi r4,r1,INT_FRAME_SIZE+STACK_UNDERHEAD /* size of frame */ stw r4,TSS+KSP(r2) /* save kernel stack pointer */ diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index e89462a39f37..b6c338946fc3 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -1,5 +1,5 @@ /* - * $Id: idle.c,v 1.50 1998/08/18 16:19:25 cort Exp $ + * $Id: idle.c,v 1.56 1998/10/13 19:14:36 paulus Exp $ * * Idle daemon for PowerPC. Idle daemon will handle any action * that needs to be taken when the system becomes idle. @@ -11,8 +11,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#define __KERNEL_SYSCALLS__ - #include #include #include @@ -32,9 +30,6 @@ #include #include #include -#ifdef CONFIG_PMAC -#include -#endif void zero_paged(void); void power_save(void); @@ -60,15 +55,7 @@ int idled(void *unused) if ( !current->need_resched && zero_paged_on ) zero_paged(); if ( !current->need_resched && htab_reclaim_on ) htab_reclaim(); - - /* - * Only processor 1 may sleep now since processor 2 would - * never wake up. Need to add timer code for processor 2 - * then it can sleep. -- Cort - */ -#ifndef __SMP__ if ( !current->need_resched ) power_save(); -#endif /* __SMP__ */ run_task_queue(&tq_scheduler); schedule(); } @@ -93,15 +80,9 @@ int cpu_idle(void *unused) */ asmlinkage int sys_idle(void) { - extern int media_bay_task(void *); if(current->pid != 0) return -EPERM; -#ifdef CONFIG_PMAC - if (media_bay_present) - kernel_thread(media_bay_task, NULL, 0); -#endif - idled(NULL); return 0; /* should never execute this but it makes gcc happy -- Cort */ } diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 68f58b0a9c32..a180e5f0a781 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -9,7 +9,7 @@ * Adapted for Power Macintosh by Paul Mackerras * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). - * + * * This file contains the code used by various IRQ handling routines: * asking for different IRQ's should be done through these routines * instead of just grabbing them. Thus setups with different IRQ numbers @@ -63,8 +63,9 @@ extern void apus_init_IRQ(void); extern void amiga_disable_irq(unsigned int irq); extern void amiga_enable_irq(unsigned int irq); static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { } -static volatile unsigned char *gg2_int_ack_special; +static volatile unsigned char *chrp_int_ack_special; extern volatile unsigned long ipi_count; +static void pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base); #ifdef CONFIG_APUS /* Rename a few functions. Requires the CONFIG_APUS protection. */ @@ -88,6 +89,7 @@ void (*unmask_irq)(unsigned int irq_nr); #define VEC_SPUR (24) #undef SHOW_IRQ +#undef SHOW_GATWICK_IRQS #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) #define cached_21 (((char *)(cached_irq_mask))[3]) #define cached_A1 (((char *)(cached_irq_mask))[2]) @@ -96,6 +98,7 @@ void (*unmask_irq)(unsigned int irq_nr); unsigned int local_bh_count[NR_CPUS]; unsigned int local_irq_count[NR_CPUS]; int max_irqs; +int max_real_irqs; static struct irqaction *irq_action[NR_IRQS]; static int spurious_interrupts = 0; static unsigned int cached_irq_mask[NR_MASK_WORDS]; @@ -111,11 +114,32 @@ struct pmac_irq_hw { }; /* XXX these addresses should be obtained from the device tree */ -volatile struct pmac_irq_hw *pmac_irq_hw[2] = { +volatile struct pmac_irq_hw *pmac_irq_hw[4] = { (struct pmac_irq_hw *) 0xf3000020, (struct pmac_irq_hw *) 0xf3000010, + (struct pmac_irq_hw *) 0xf4000020, + (struct pmac_irq_hw *) 0xf4000010, }; +/* This is the interrupt used on the main controller for the secondary + controller. Happens on PowerBooks G3 Series (a second mac-io) + -- BenH + */ +static int second_irq = -999; + +/* Returns the number of 0's to the left of the most significant 1 bit */ +static inline int cntlzw(int bits) +{ + int lz; + + asm ("cntlzw %0,%1" : "=r" (lz) : "r" (bits)); + return lz; +} + +static inline void sync(void) +{ + asm volatile ("sync"); +} /* nasty hack for shared irq's since we need to do kmalloc calls but * can't very very early in the boot when we need to do a request irq. @@ -173,12 +197,12 @@ void i8259_mask_and_ack_irq(int irq_nr) /* spin_unlock(&irq_controller_lock);*/ } -void pmac_mask_and_ack_irq(int irq_nr) +void __pmac pmac_mask_and_ack_irq(int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; - if (irq_nr >= max_irqs) + if ((unsigned)irq_nr >= max_irqs) return; /*spin_lock(&irq_controller_lock);*/ @@ -188,13 +212,15 @@ void pmac_mask_and_ack_irq(int irq_nr) out_le32(&pmac_irq_hw[i]->ack, bit); out_le32(&pmac_irq_hw[i]->enable, cached_irq_mask[i]); out_le32(&pmac_irq_hw[i]->ack, bit); + /* make sure ack gets to controller before we enable interrupts */ + sync(); /*spin_unlock(&irq_controller_lock);*/ /*if ( irq_controller_lock.lock ) panic("irq controller lock still held in mask and ack\n");*/ } -void chrp_mask_and_ack_irq(int irq_nr) +void __openfirmware chrp_mask_and_ack_irq(int irq_nr) { /* spinlocks are done by i8259_mask_and_ack() - Cort */ if (is_8259_irq(irq_nr)) @@ -211,12 +237,12 @@ static void i8259_set_irq_mask(int irq_nr) } } -static void pmac_set_irq_mask(int irq_nr) +static void __pmac pmac_set_irq_mask(int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; - if (irq_nr >= max_irqs) + if ((unsigned)irq_nr >= max_irqs) return; /* enable unmasked interrupts */ @@ -251,19 +277,20 @@ static void i8259_unmask_irq(unsigned int irq_nr) i8259_set_irq_mask(irq_nr); } -static void pmac_mask_irq(unsigned int irq_nr) +static void __pmac pmac_mask_irq(unsigned int irq_nr) { clear_bit(irq_nr, cached_irq_mask); pmac_set_irq_mask(irq_nr); + sync(); } -static void pmac_unmask_irq(unsigned int irq_nr) +static void __pmac pmac_unmask_irq(unsigned int irq_nr) { set_bit(irq_nr, cached_irq_mask); pmac_set_irq_mask(irq_nr); } -static void chrp_mask_irq(unsigned int irq_nr) +static void __openfirmware chrp_mask_irq(unsigned int irq_nr) { if (is_8259_irq(irq_nr)) i8259_mask_irq(irq_nr); @@ -271,7 +298,7 @@ static void chrp_mask_irq(unsigned int irq_nr) openpic_disable_irq(irq_to_openpic(irq_nr)); } -static void chrp_unmask_irq(unsigned int irq_nr) +static void __openfirmware chrp_unmask_irq(unsigned int irq_nr) { if (is_8259_irq(irq_nr)) i8259_unmask_irq(irq_nr); @@ -325,7 +352,7 @@ int get_irq_list(char *buf) for (i = 0 ; i < NR_IRQS ; i++) { action = irq_action[i]; - if (!action || !action->handler) + if ((!action || !action->handler) && (i != second_irq)) continue; len += sprintf(buf+len, "%3d: ", i); #ifdef __SMP__ @@ -341,7 +368,10 @@ int get_irq_list(char *buf) len += sprintf(buf+len, " 82c59 "); break; case _MACH_Pmac: - len += sprintf(buf+len, " PMAC-PIC "); + if (i < 64) + len += sprintf(buf+len, " PMAC-PIC "); + else + len += sprintf(buf+len, " GATWICK "); break; case _MACH_chrp: if ( is_8259_irq(i) ) @@ -354,23 +384,26 @@ int get_irq_list(char *buf) break; } - len += sprintf(buf+len, " %s",action->name); - for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ", %s", action->name); - } - len += sprintf(buf+len, "\n"); + if (i != second_irq) { + len += sprintf(buf+len, " %s",action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ", %s", action->name); + } + len += sprintf(buf+len, "\n"); + } else + len += sprintf(buf+len, " Gatwick secondary IRQ controller\n"); } #ifdef __SMP__ /* should this be per processor send/receive? */ - len += sprintf(buf+len, "IPI: %10lu\n", ipi_count); + len += sprintf(buf+len, "IPI: %10lu", ipi_count); for ( i = 0 ; i <= smp_num_cpus-1; i++ ) len += sprintf(buf+len," "); - len += sprintf(buf+len, " interprocessor messages received\n"); + len += sprintf(buf+len, " interprocessor messages received\n"); #endif len += sprintf(buf+len, "BAD: %10u",spurious_interrupts); for ( i = 0 ; i <= smp_num_cpus-1; i++ ) len += sprintf(buf+len," "); - len += sprintf(buf+len, " spurious or short\n"); + len += sprintf(buf+len, " spurious or short\n"); return len; } @@ -604,7 +637,6 @@ void __global_restore_flags(unsigned long flags) #endif /* __SMP__ */ - asmlinkage void do_IRQ(struct pt_regs *regs) { int irq; @@ -627,9 +659,6 @@ asmlinkage void do_IRQ(struct pt_regs *regs) if (!atomic_read(&n_lost_interrupts)) { extern void smp_message_recv(void); - goto out; - - ipi_count++; smp_message_recv(); goto out; } @@ -642,20 +671,48 @@ asmlinkage void do_IRQ(struct pt_regs *regs) switch ( _machine ) { case _MACH_Pmac: - for (irq = max_irqs - 1; irq > 0; irq -= 32) { - int i = irq >> 5, lz; + for (irq = max_real_irqs - 1; irq > 0; irq -= 32) { + int i = irq >> 5; bits = ld_le32(&pmac_irq_hw[i]->flag) | lost_interrupts[i]; if (bits == 0) continue; - /* lz = number of 0 bits to left of most sig. 1 */ - asm ("cntlzw %0,%1" : "=r" (lz) : "r" (bits)); - irq -= lz; + irq -= cntlzw(bits); break; } + + /* Here, we handle interrupts coming from Gatwick, + * normal interrupt code will take care of acking and + * masking the irq on Gatwick itself but we ack&mask + * the Gatwick main interrupt on Heathrow now. It's + * unmasked later, after interrupt handling. -- BenH + */ + if (irq == second_irq) { + mask_and_ack_irq(second_irq); + for (irq = max_irqs - 1; irq > max_real_irqs; irq -= 32) { + int i = irq >> 5; + bits = ld_le32(&pmac_irq_hw[i]->flag) + | lost_interrupts[i]; + if (bits == 0) + continue; + irq -= cntlzw(bits); + break; + } + /* If not found, on exit, irq is 63 (128-1-32-32). + * We set it to -1 and revalidate second controller + */ + if (irq < max_real_irqs) { + irq = -1; + unmask_irq(second_irq); + } +#ifdef SHOW_GATWICK_IRQS + printk("Gatwick irq %d (i:%d, bits:0x%08lx\n", irq, i, bits); +#endif + } + break; case _MACH_chrp: - irq = openpic_irq(0); + irq = openpic_irq(0); if (irq == IRQ_8259_CASCADE) { /* @@ -663,7 +720,7 @@ asmlinkage void do_IRQ(struct pt_regs *regs) * * This should go in the above mask/ack code soon. -- Cort */ - irq = *gg2_int_ack_special; + irq = *chrp_int_ack_special; /* * Acknowledge as soon as possible to allow i8259 * interrupt nesting @@ -740,11 +797,13 @@ apus_out: } #endif } - + if (irq < 0) { - printk(KERN_DEBUG "Bogus interrupt from PC = %lx\n", regs->nip); + printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", + irq, regs->nip); + spurious_interrupts++; goto out; - } + } #else /* CONFIG_8xx */ /* For MPC8xx, read the SIVEC register and shift the bits down @@ -753,9 +812,7 @@ apus_out: bits = ((immap_t *)MBX_IMAP_ADDR)->im_siu_conf.sc_sivec; irq = bits >> 26; #endif /* CONFIG_8xx */ - mask_and_ack_irq(irq); - status = 0; action = irq_action[irq]; kstat.irqs[cpu][irq]++; @@ -765,14 +822,10 @@ apus_out: do { status |= action->flags; action->handler(irq, action->dev_id, regs); - /*if (status & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq);*/ action = action->next; } while ( action ); __cli(); - /* spin_lock(&irq_controller_lock);*/ unmask_irq(irq); - /* spin_unlock(&irq_controller_lock);*/ } else { #ifndef CONFIG_8xx if ( irq == 7 ) /* i8259 gives us irq 7 on 'short' intrs */ @@ -781,8 +834,13 @@ apus_out: disable_irq( irq ); } + /* This was a gatwick sub-interrupt, we re-enable them on Heathrow + now */ + if (_machine == _MACH_Pmac && irq >= max_real_irqs) + unmask_irq(second_irq); + /* make sure we don't miss any cascade intrs due to eoi-ing irq 2 */ -#ifndef CONFIG_8xx +#ifndef CONFIG_8xx if ( is_prep && (irq > 7) ) goto retry_cascade; /* do_bottom_half is called if necessary from int_return in head.S */ @@ -808,12 +866,16 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) #ifdef SHOW_IRQ printk("request_irq(): irq %d handler %08x name %s dev_id %04x\n", - irq,handler,devname,dev_id); + irq,(int)handler,devname,(int)dev_id); #endif /* SHOW_IRQ */ if (irq >= NR_IRQS) return -EINVAL; + /* Cannot allocate second controller IRQ */ + if (irq == second_irq) + return -EBUSY; + if (!handler) { /* Free */ @@ -838,7 +900,7 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) cli(); action->handler = handler; - action->flags = irqflags; + action->flags = irqflags; action->mask = 0; action->name = devname; action->dev_id = dev_id; @@ -909,6 +971,9 @@ __initfunc(void init_IRQ(void)) { extern void xmon_irq(int, void *, struct pt_regs *); int i; + struct device_node *irqctrler; + unsigned long addr; + struct device_node *np; #ifndef CONFIG_8xx switch (_machine) @@ -918,12 +983,59 @@ __initfunc(void init_IRQ(void)) mask_irq = pmac_mask_irq; unmask_irq = pmac_unmask_irq; - /* G3 powermacs have 64 interrupts, others have 32 */ - max_irqs = (find_devices("mac-io") ? 64 : 32); - printk("System has %d possible interrupts\n", max_irqs); + /* G3 powermacs have 64 interrupts, G3 Series PowerBook have 128, + others have 32 */ + max_irqs = max_real_irqs = 32; + irqctrler = find_devices("mac-io"); + if (irqctrler) + { + max_real_irqs = 64; + if (irqctrler->next) + max_irqs = 128; + else + max_irqs = 64; + } + + /* get addresses of first controller */ + if (irqctrler) { + if (irqctrler->n_addrs > 0) { + addr = (unsigned long) + ioremap(irqctrler->addrs[0].address, 0x40); + for (i = 0; i < 2; ++i) + pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) + (addr + (2 - i) * 0x10); + } + + /* get addresses of second controller */ + irqctrler = (irqctrler->next) ? irqctrler->next : NULL; + if (irqctrler && irqctrler->n_addrs > 0) { + addr = (unsigned long) + ioremap(irqctrler->addrs[0].address, 0x40); + for (i = 2; i < 4; ++i) + pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) + (addr + (4 - i) * 0x10); + } + } + /* disable all interrupts in all controllers */ for (i = 0; i * 32 < max_irqs; ++i) out_le32(&pmac_irq_hw[i]->enable, 0); + + + /* get interrupt line of secondary interrupt controller */ + if (irqctrler) { + second_irq = irqctrler->intrs[0].line; + printk(KERN_INFO "irq: secondary controller on irq %d\n", + (int)second_irq); + if (device_is_compatible(irqctrler, "gatwick")) + pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs); + enable_irq(second_irq); + } + printk("System has %d possible interrupts\n", max_irqs); + if (max_irqs != max_real_irqs) + printk(KERN_DEBUG "%d interrupts on main controller\n", + max_real_irqs); + #ifdef CONFIG_XMON request_irq(20, xmon_irq, 0, "NMI", 0); #endif /* CONFIG_XMON */ @@ -932,8 +1044,15 @@ __initfunc(void init_IRQ(void)) mask_and_ack_irq = chrp_mask_and_ack_irq; mask_irq = chrp_mask_irq; unmask_irq = chrp_unmask_irq; - gg2_int_ack_special = (volatile unsigned char *) - ioremap(GG2_INT_ACK_SPECIAL, 1); + + if ( !(np = find_devices("pci") ) ) + printk("Cannot find pci to get ack address\n"); + else + { + chrp_int_ack_special = (volatile unsigned char *) + (*(unsigned long *)get_property(np, + "8259-interrupt-acknowledge", NULL)); + } openpic_init(1); i8259_init(); cached_irq_mask[0] = cached_irq_mask[1] = ~0UL; @@ -993,3 +1112,61 @@ __initfunc(void init_IRQ(void)) } #endif /* CONFIG_8xx */ } + +/* This routine will fix some missing interrupt values in the device tree + * on the gatwick mac-io controller used by some PowerBooks + */ +__pmac +static void pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) +{ + struct device_node *node; + static struct interrupt_info int_pool[4]; + + memset(int_pool, 0, sizeof(int_pool)); + node = gw->child; + while(node) + { + /* Fix SCC */ + if (strcasecmp(node->name, "escc") == 0) + if (node->child && node->child->n_intrs == 0) + { + node->child->n_intrs = 1; + node->child->intrs = &int_pool[0]; + int_pool[0].line = 15+irq_base; + printk(KERN_INFO "irq: fixed SCC on second controller (%d)\n", + int_pool[0].line); + } + /* Fix media-bay & left SWIM */ + if (strcasecmp(node->name, "media-bay") == 0) + { + struct device_node* ya_node; + + if (node->n_intrs == 0) + { + node->n_intrs = 1; + node->intrs = &int_pool[1]; + int_pool[1].line = 29+irq_base; + printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n", + int_pool[1].line); + } + ya_node = node->child; + while(ya_node) + { + if ((strcasecmp(ya_node->name, "floppy") == 0) && + ya_node->n_intrs == 0) + { + ya_node->n_intrs = 2; + ya_node->intrs = &int_pool[2]; + int_pool[2].line = 19+irq_base; + int_pool[3].line = 1+irq_base; + printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n", + int_pool[2].line, int_pool[3].line); + } + ya_node = ya_node->sibling; + } + } + node = node->sibling; + } + +} + diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 1566a18799b6..f13508d96b33 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -363,9 +363,25 @@ _GLOBAL(_get_THRM1) mfspr r3,THRM1 blr +_GLOBAL(_get_THRM2) + mfspr r3,THRM2 + blr + +_GLOBAL(_get_THRM3) + mfspr r3,THRM3 + blr + _GLOBAL(_set_THRM1) mtspr THRM1,r3 blr + +_GLOBAL(_set_THRM2) + mtspr THRM2,r3 + blr + +_GLOBAL(_set_THRM3) + mtspr THRM3,r3 + blr _GLOBAL(_get_L2CR) mfspr r3,L2CR @@ -453,7 +469,6 @@ _GLOBAL(name) \ #define __NR__exit __NR_exit SYSCALL(idle) -SYSCALL(setup) SYSCALL(sync) SYSCALL(setsid) SYSCALL(write) @@ -490,12 +505,12 @@ sys_call_table: .long sys_mknod .long sys_chmod /* 15 */ .long sys_lchown - .long sys_ni_syscall + .long sys_ni_syscall /* old break syscall holder */ .long sys_stat .long sys_lseek .long sys_getpid /* 20 */ .long sys_mount - .long sys_umount + .long sys_oldumount .long sys_setuid .long sys_getuid .long sys_stime /* 25 */ @@ -504,11 +519,11 @@ sys_call_table: .long sys_fstat .long sys_pause .long sys_utime /* 30 */ - .long /*sys_stty*/ sys_ni_syscall - .long /*sys_gtty*/ sys_ni_syscall + .long sys_ni_syscall /* old stty syscall holder */ + .long sys_ni_syscall /* old gtty syscall holder */ .long sys_access .long sys_nice - .long /*sys_ftime*/ sys_ni_syscall /* 35 */ + .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ .long sys_sync .long sys_kill .long sys_rename @@ -517,7 +532,7 @@ sys_call_table: .long sys_dup .long sys_pipe .long sys_times - .long /*sys_prof*/ sys_ni_syscall + .long sys_ni_syscall /* old prof syscall holder */ .long sys_brk /* 45 */ .long sys_setgid .long sys_getgid @@ -525,13 +540,13 @@ sys_call_table: .long sys_geteuid .long sys_getegid /* 50 */ .long sys_acct - .long /*sys_phys*/ sys_ni_syscall - .long /*sys_lock*/ sys_ni_syscall + .long sys_umount /* recycled never used phys() */ + .long sys_ni_syscall /* old lock syscall holder */ .long sys_ioctl .long sys_fcntl /* 55 */ - .long /*sys_mpx*/ sys_ni_syscall + .long sys_ni_syscall /* old mpx syscall holder */ .long sys_setpgid - .long /*sys_ulimit*/ sys_ni_syscall + .long sys_ni_syscall /* old ulimit syscall holder */ .long sys_olduname .long sys_umask /* 60 */ .long sys_chroot @@ -562,7 +577,7 @@ sys_call_table: .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir /* was sys_readdir */ + .long old_readdir .long sys_mmap /* 90 */ .long sys_munmap .long sys_truncate @@ -571,7 +586,7 @@ sys_call_table: .long sys_fchown /* 95 */ .long sys_getpriority .long sys_setpriority - .long /*sys_profil*/ sys_ni_syscall + .long sys_ni_syscall /* old profil syscall holder */ .long sys_statfs .long sys_fstatfs /* 100 */ .long sys_ioperm @@ -610,7 +625,7 @@ sys_call_table: .long sys_bdflush .long sys_sysfs /* 135 */ .long sys_personality - .long 0 /* for afs_syscall */ + .long sys_ni_syscall /* for afs_syscall */ .long sys_setfsuid .long sys_setfsgid .long sys_llseek /* 140 */ @@ -638,28 +653,28 @@ sys_call_table: .long sys_nanosleep .long sys_mremap .long sys_setresuid - .long sys_getresuid /* 165 */ + .long sys_getresuid /* 165 */ .long sys_query_module .long sys_poll .long sys_nfsservctl - .long sys_setresgid - .long sys_getresgid /* 170 */ + .long sys_setresgid + .long sys_getresgid /* 170 */ .long sys_prctl .long sys_rt_sigreturn .long sys_rt_sigaction .long sys_rt_sigprocmask - .long sys_rt_sigpending /* 175 */ + .long sys_rt_sigpending /* 175 */ .long sys_rt_sigtimedwait .long sys_rt_sigqueueinfo .long sys_rt_sigsuspend .long sys_pread - .long sys_pwrite /* 180 */ + .long sys_pwrite /* 180 */ .long sys_chown .long sys_getcwd .long sys_capget .long sys_capset - .long sys_sigaltstack /* 185 */ + .long sys_sigaltstack /* 185 */ .long sys_sendfile - .long sys_ni_syscall - .long sys_ni_syscall + .long sys_ni_syscall /* streams1 */ + .long sys_ni_syscall /* streams2 */ .space (NR_syscalls-183)*4 diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 8a912901019b..359446f4fecd 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1,5 +1,5 @@ /* - * $Id: pci.c,v 1.38 1998/08/31 06:28:02 cort Exp $ + * $Id: pci.c,v 1.39 1998/10/13 20:59:04 cort Exp $ * Common pmac/prep/chrp pci routines. -- Cort */ @@ -164,7 +164,7 @@ __initfunc(void get_property(find_path_device("/"), "model", NULL),3) ) { isa_io_base = 0xfe000000; - set_config_access_method(raven); + set_config_access_method(grackle); } else { diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index 481f69e2cd91..7763059f74b0 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -40,7 +40,6 @@ static void add_bridges(struct device_node *dev, unsigned long *mem_ptr); #define BANDIT_COHERENT 0x40 __pmac - void *pci_io_base(unsigned int bus) { struct bridge_data *bp; @@ -50,6 +49,7 @@ void *pci_io_base(unsigned int bus) return bp->io_base; } +__pmac int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr, unsigned char *devfn_ptr) { @@ -68,6 +68,7 @@ int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr, return 0; } +__pmac int pmac_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char *val) { @@ -90,6 +91,7 @@ int pmac_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } +__pmac int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned short *val) { @@ -114,6 +116,7 @@ int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } +__pmac int pmac_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int *val) { @@ -138,6 +141,7 @@ int pmac_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } +__pmac int pmac_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char val) { @@ -159,6 +163,7 @@ int pmac_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } +__pmac int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned short val) { @@ -182,6 +187,7 @@ int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } +__pmac int pmac_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int val) { @@ -406,7 +412,7 @@ __initfunc(static void add_bridges(struct device_node *dev, unsigned long *mem_p ioremap(0xfec00000, 0x1000); bp->cfg_data = (volatile unsigned char *) ioremap(0xfee00000, 0x1000); - bp->io_base = (void *) ioremap(0xfe000000, 0x10000); + bp->io_base = (void *) ioremap(0xfe000000, 0x20000); } if (isa_io_base == 0) isa_io_base = (unsigned long) bp->io_base; diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c index a171fd332e54..499e8b6a5470 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/kernel/pmac_setup.c @@ -49,9 +49,9 @@ #include #include #include -#include #include #include +#include #include "time.h" unsigned char drive_info; @@ -64,7 +64,6 @@ extern void zs_kgdb_hook(int tty_num); static void ohare_init(void); __pmac - int pmac_get_cpuinfo(char *buffer) { @@ -151,6 +150,7 @@ pmac_get_cpuinfo(char *buffer) #define MKDEV_SD_PARTITION(i) MKDEV(SD_MAJOR_NUMBER(i), SD_MINOR_NUMBER(i)) #define MKDEV_SD(index) MKDEV_SD_PARTITION((index) << 4) +__init kdev_t sd_find_target(void *host, int tgt) { Scsi_Disk *dp; @@ -168,13 +168,13 @@ kdev_t sd_find_target(void *host, int tgt) * Dummy mksound function that does nothing. * The real one is in the dmasound driver. */ +__pmac static void pmac_mksound(unsigned int hz, unsigned int ticks) { } static volatile u32 *sysctrl_regs; -static volatile u32 *feature_addr; __initfunc(void pmac_setup_arch(unsigned long *memory_start_p, unsigned long *memory_end_p)) @@ -206,10 +206,11 @@ pmac_setup_arch(unsigned long *memory_start_p, unsigned long *memory_end_p)) and some registers used by smp boards */ sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); __ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY)); + ohare_init(); *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p); - ohare_init(); + feature_init(); #ifdef CONFIG_KGDB zs_kgdb_hook(0); @@ -234,39 +235,19 @@ pmac_setup_arch(unsigned long *memory_start_p, unsigned long *memory_end_p)) __initfunc(static void ohare_init(void)) { - struct device_node *np; - - np = find_devices("ohare"); - if (np == 0) - return; - if (np->next != 0) - printk(KERN_WARNING "only using the first ohare\n"); - if (np->n_addrs == 0) { - printk(KERN_ERR "No addresses for %s\n", np->full_name); - return; - } - feature_addr = (volatile u32 *) - ioremap(np->addrs[0].address + OHARE_FEATURE_REG, 4); - - if (find_devices("via-pmu") == 0) { - printk(KERN_INFO "Twiddling the magic ohare bits\n"); - out_le32(feature_addr, STARMAX_FEATURES); - } else { - out_le32(feature_addr, in_le32(feature_addr) | PBOOK_FEATURES); - printk(KERN_DEBUG "feature reg = %x\n", in_le32(feature_addr)); - } - /* * Turn on the L2 cache. * We assume that we have a PSX memory controller iff * we have an ohare I/O controller. */ - if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { - if (sysctrl_regs[4] & 0x10) - sysctrl_regs[4] |= 0x04000020; - else - sysctrl_regs[4] |= 0x04000000; - printk(KERN_INFO "Level 2 cache enabled\n"); + if (find_devices("ohare") != NULL) { + if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { + if (sysctrl_regs[4] & 0x10) + sysctrl_regs[4] |= 0x04000020; + else + sysctrl_regs[4] |= 0x04000000; + printk(KERN_INFO "Level 2 cache enabled\n"); + } } } @@ -277,8 +258,10 @@ int boot_target; int boot_part; kdev_t boot_dev; -__initfunc(void powermac_init(void)) +void __init powermac_init(void) { + if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) + return; adb_init(); pmac_nvram_init(); if (_machine == _MACH_Pmac) { @@ -363,7 +346,9 @@ __initfunc(void find_boot_device(void)) #endif } -__initfunc(void note_bootable_part(kdev_t dev, int part)) +/* can't be initfunc - can be called whenever a disk is first accessed */ +__pmac +void note_bootable_part(kdev_t dev, int part) { static int found_boot = 0; char *p; diff --git a/arch/ppc/kernel/pmac_support.c b/arch/ppc/kernel/pmac_support.c index c88c8bae9738..0196c5eb64a6 100644 --- a/arch/ppc/kernel/pmac_support.c +++ b/arch/ppc/kernel/pmac_support.c @@ -25,8 +25,7 @@ static int nvram_mult; #define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */ -__pmac - +__init void pmac_nvram_init(void) { struct device_node *dp; diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 66e8f2a0536f..d48f55ff4883 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -24,6 +24,7 @@ #include #include #include +#include #define __KERNEL_SYSCALLS__ #include @@ -100,7 +101,6 @@ EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strspn); EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strncmp); -EXPORT_SYMBOL(strnicmp); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memmove); @@ -159,6 +159,10 @@ EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(xchg_u32); +#ifndef CONFIG_MACH_SPECIFIC +EXPORT_SYMBOL(_machine); +#endif + EXPORT_SYMBOL(adb_request); EXPORT_SYMBOL(adb_autopoll); EXPORT_SYMBOL(adb_register); @@ -174,10 +178,15 @@ EXPORT_SYMBOL(sleep_notifier_list); EXPORT_SYMBOL(abort); EXPORT_SYMBOL(find_devices); EXPORT_SYMBOL(find_type_devices); +EXPORT_SYMBOL(find_compatible_devices); EXPORT_SYMBOL(find_path_device); +EXPORT_SYMBOL(find_phandle); EXPORT_SYMBOL(get_property); EXPORT_SYMBOL(pci_io_base); EXPORT_SYMBOL(pci_device_loc); +EXPORT_SYMBOL(feature_set); +EXPORT_SYMBOL(feature_clear); +EXPORT_SYMBOL(feature_test); EXPORT_SYMBOL(note_scsi_host); EXPORT_SYMBOL(kd_mksound); #ifdef CONFIG_PMAC diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c index e9aa716ea619..b7d94d2086da 100644 --- a/arch/ppc/kernel/prep_pci.c +++ b/arch/ppc/kernel/prep_pci.c @@ -1,5 +1,5 @@ /* - * $Id: prep_pci.c,v 1.22 1998/08/05 20:11:15 cort Exp $ + * $Id: prep_pci.c,v 1.23 1998/10/21 10:52:24 cort Exp $ * PReP pci functions. * Originally by Gary Thomas * rewritten and updated by Cort Dougan (cort@cs.nmt.edu) @@ -462,6 +462,11 @@ __initfunc(unsigned long route_pci_interrupts(void)) Motherboard_map = Utah_pci_IRQ_map; Motherboard_routes = Utah_pci_IRQ_routes; break; + case 0xE0: /* MTX -- close enough?? to Genesis, so reuse it */ + Motherboard_map_name = "Motorola MTX"; + Motherboard_map = Genesis_pci_IRQ_map; + Motherboard_routes = Genesis_pci_IRQ_routes; + break; case 0x40: /* PowerStack */ default: /* Can't hurt, can it? */ Motherboard_map_name = "Blackhawk (Powerstack)"; diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index 59716027d519..e596f9ea5086 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -196,7 +196,7 @@ prep_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p)) sprintf(cmd_line,"%s console=tty0 console=ttyS0,9600n8", cmd_line); printk("Boot arguments: %s\n", cmd_line); -#ifdef CONFIG_CS4232 +#ifdef CONFIG_SOUND_CS4232 /* * setup proper values for the cs4232 driver so we don't have * to recompile for the motorola or ibm workstations sound systems. @@ -233,8 +233,7 @@ prep_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p)) } } } -#endif /* CONFIG_CS4232 */ - +#endif /* CONFIG_SOUND_CS4232 */ /*print_residual_device_info();*/ request_region(0x20,0x20,"pic1"); diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 6b729a87cb0e..5ea55cee9200 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -163,14 +163,19 @@ switch_to(struct task_struct *prev, struct task_struct *new) #endif #ifdef SHOW_TASK_SWITCHES - printk("%s/%d -> %s/%d NIP %08lx cpu %d sfr %d lock %x\n", + printk("%s/%d -> %s/%d NIP %08lx cpu %d lock %x root %x/%x\n", prev->comm,prev->pid, new->comm,new->pid,new->tss.regs->nip,new->processor, - new->tss.smp_fork_ret,scheduler_lock.lock); + scheduler_lock.lock,new->fs->root,prev->fs->root); #endif #ifdef __SMP__ /* avoid complexity of lazy save/restore of fpu - * by just saving it every time we switch out -- Cort + * by just saving it every time we switch out if + * this task used the fpu during the last quantum. + * + * If it tries to use the fpu again, it'll trap and + * reload its fp regs. + * -- Cort */ if ( prev->tss.regs->msr & MSR_FP ) smp_giveup_fpu(prev); @@ -383,6 +388,7 @@ asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, { int res; + lock_kernel(); res = do_fork(SIGCHLD, regs->gpr[1], regs); /* only parent returns here */ @@ -404,18 +410,23 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, { int error; char * filename; - lock_kernel(); filename = getname((char *) a0); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; +#ifdef __SMP__ + if ( regs->msr & MSR_FP ) + smp_giveup_fpu(current); +#else if ( last_task_used_math == current ) - last_task_used_math = NULL; + giveup_fpu(); +#endif error = do_execve(filename, (char **) a1, (char **) a2, regs); putname(filename); out: unlock_kernel(); + return error; } diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index 60a1ffd5243f..da9d7a04c1c3 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -1,5 +1,5 @@ /* - * $Id: prom.c,v 1.39 1998/09/18 09:14:52 paulus Exp $ + * $Id: prom.c,v 1.46 1998/11/11 03:55:09 paulus Exp $ * * Procedures for interfacing to the Open Firmware PROM on * Power Macintosh computers. @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,13 @@ struct isa_reg_property { unsigned size; }; +struct pci_intr_map { + struct pci_address addr; + unsigned dunno; + phandle int_ctrler; + unsigned intr; +}; + typedef unsigned long interpret_func(struct device_node *, unsigned long); static interpret_func interpret_pci_props; static interpret_func interpret_dbdma_props; @@ -90,6 +98,31 @@ unsigned int old_rtas = 0; static struct device_node *allnodes = 0; +static void clearscreen(void); + +#ifdef CONFIG_BOOTX_TEXT + +static void drawchar(char c); +static void drawstring(const char *c); +static void scrollscreen(void); + +static void draw_byte(unsigned char c, long locX, long locY); +static void draw_byte_32(unsigned char *bits, unsigned long *base); +static void draw_byte_16(unsigned char *bits, unsigned long *base); +static void draw_byte_8(unsigned char *bits, unsigned long *base); + +static long g_loc_X; +static long g_loc_Y; +static long g_max_loc_X; +static long g_max_loc_Y; + +#define cmapsz (16*256) + +static unsigned char vga_font[cmapsz]; + +#endif + + static void *call_prom(const char *service, int nargs, int nret, ...); static void prom_exit(void); static unsigned long copy_device_tree(unsigned long, unsigned long); @@ -100,6 +133,7 @@ static unsigned long finish_node(struct device_node *, unsigned long, static void relocate_nodes(void); static unsigned long check_display(unsigned long); static int prom_next_node(phandle *); +static void *early_get_property(unsigned long, unsigned long, char *); extern void enter_rtas(void *); extern unsigned long reloc_offset(void); @@ -133,7 +167,7 @@ boot_infos_t *boot_infos = 0; /* init it so it's in data segment not bss */ #define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long)) -__openfirmware +__init static void prom_exit() { @@ -148,7 +182,7 @@ prom_exit() ; } -__openfirmware +__init void prom_enter(void) { @@ -161,7 +195,7 @@ prom_enter(void) RELOC(prom)(&args); } -__openfirmware +__init static void * call_prom(const char *service, int nargs, int nret, ...) { @@ -183,13 +217,23 @@ call_prom(const char *service, int nargs, int nret, ...) return prom_args.args[nargs]; } -__openfirmware +__init void prom_print(const char *msg) { const char *p, *q; unsigned long offset = reloc_offset(); + if (RELOC(prom_stdout) == 0) + { +#ifdef CONFIG_BOOTX_TEXT + if (RELOC(boot_infos) != 0) + drawstring(msg); +#endif + return; + } + + for (p = msg; *p != 0; p = q) { for (q = p; *q != 0 && *q != '\n'; ++q) ; @@ -208,7 +252,7 @@ prom_print(const char *msg) * We enter here early on, when the Open Firmware prom is still * handling exceptions and the MMU hash table for us. */ -__openfirmware +__init void prom_init(int r3, int r4, prom_entry pp) { @@ -217,10 +261,6 @@ prom_init(int r3, int r4, prom_entry pp) unsigned long offset = reloc_offset(); int l; char *p, *d; -#ifdef __SMP__ - if ( RELOC(first_cpu_booted) ) - return; -#endif /* __SMP__ */ /* check if we're apus, return if we are */ if ( r3 == 0x61707573 ) @@ -230,24 +270,45 @@ prom_init(int r3, int r4, prom_entry pp) * set up some pointers and return. */ if (r3 == 0x426f6f58 && pp == NULL) { boot_infos_t *bi = (boot_infos_t *) r4; - unsigned int *screen; - int nw, ln; unsigned long space; + unsigned long ptr, x; + char *model; + + RELOC(boot_infos) = PTRUNRELOC(bi); - /* first clear the screen */ - for (ln = 0; ln < bi->dispDeviceRect[3]; ++ln) { - screen = (unsigned int *) (bi->dispDeviceBase - + ln * bi->dispDeviceRowBytes); - nw = bi->dispDeviceRect[2] * bi->dispDeviceDepth / 32; - for (; nw > 0; --nw) - *screen++ = 0; + clearscreen(); + +#ifdef CONFIG_BOOTX_TEXT + RELOC(g_loc_X) = 0; + RELOC(g_loc_Y) = 0; + RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8; + RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16; + prom_print(RELOC("Welcome to Linux, kernel " UTS_RELEASE " booting...\n")); +#endif + + /* + * XXX If this is an iMac, turn off the USB controller. + */ + model = (char *) early_get_property + (r4 + bi->deviceTreeOffset, 4, RELOC("model")); + if (model && strcmp(model, RELOC("iMac,1")) == 0) { + out_le32((unsigned *)0x80880008, 1); /* XXX */ } - RELOC(boot_infos) = PTRUNRELOC(bi); space = bi->deviceTreeOffset + bi->deviceTreeSize; if (bi->ramDisk) space = bi->ramDisk + bi->ramDiskSize; RELOC(klimit) = PTRUNRELOC((char *) bi + space); + + /* + * Touch each page to make sure the PTEs for them + * are in the hash table - the aim is to try to avoid + * getting DSI exceptions while copying the kernel image. + */ + for (ptr = (KERNELBASE + offset) & PAGE_MASK; + ptr < (unsigned long)bi + space; ptr += PAGE_SIZE) + x = *(volatile unsigned long *)ptr; + return; } @@ -342,7 +403,7 @@ prom_init(int r3, int r4, prom_entry pp) * So we check whether we will need to open the display, * and if so, open it now. */ -__openfirmware +__init static unsigned long check_display(unsigned long mem) { @@ -392,7 +453,7 @@ check_display(unsigned long mem) return ALIGN(mem); } -__openfirmware +__init static int prom_next_node(phandle *nodep) { @@ -415,7 +476,7 @@ prom_next_node(phandle *nodep) /* * Make a copy of the device tree from the PROM. */ -__openfirmware +__init static unsigned long copy_device_tree(unsigned long mem_start, unsigned long mem_end) { @@ -436,7 +497,7 @@ copy_device_tree(unsigned long mem_start, unsigned long mem_end) return new_start; } -__openfirmware +__init static unsigned long inspect_node(phandle node, struct device_node *dad, unsigned long mem_start, unsigned long mem_end, @@ -521,7 +582,7 @@ inspect_node(phandle node, struct device_node *dad, * It traverses the device tree and fills in the name, type, * {n_}addrs and {n_}intrs fields of each node. */ -__openfirmware +__init void finish_device_tree(void) { @@ -535,7 +596,27 @@ finish_device_tree(void) klimit = (char *) mem; } -__openfirmware +/* + * early_get_property is used to access the device tree image prepared + * by BootX very early on, before the pointers in it have been relocated. + */ +__init void * +early_get_property(unsigned long base, unsigned long node, char *prop) +{ + struct device_node *np = (struct device_node *)(base + node); + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) { + pp = (struct property *) (base + (unsigned long)pp); + if (strcmp((char *)((unsigned long)pp->name + base), + prop) == 0) { + return (void *)((unsigned long)pp->value + base); + } + } + return 0; +} + +__init static unsigned long finish_node(struct device_node *np, unsigned long mem_start, interpret_func *ifunc) @@ -556,16 +637,17 @@ finish_node(struct device_node *np, unsigned long mem_start, ifunc = NULL; else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci")) ifunc = interpret_pci_props; - else if (!strcmp(np->type, "dbdma") - || (ifunc == interpret_dbdma_props - && (!strcmp(np->type, "escc") - || !strcmp(np->type, "media-bay")))) + else if (!strcmp(np->type, "dbdma")) ifunc = interpret_dbdma_props; - else if (!strcmp(np->type, "mac-io")) + else if (!strcmp(np->type, "mac-io") + || ifunc == interpret_macio_props) ifunc = interpret_macio_props; else if (!strcmp(np->type, "isa")) ifunc = interpret_isa_props; - else + else if (!((ifunc == interpret_dbdma_props + || ifunc == interpret_macio_props) + && (!strcmp(np->type, "escc") + || !strcmp(np->type, "media-bay")))) ifunc = NULL; /* if we were booted from BootX, convert the full name */ @@ -594,7 +676,7 @@ finish_node(struct device_node *np, unsigned long mem_start, * are offsets from the start of the tree. * This procedure updates the pointers. */ -__openfirmware +__init static void relocate_nodes(void) { unsigned long base; @@ -620,13 +702,14 @@ static void relocate_nodes(void) } } -__openfirmware +__init static unsigned long interpret_pci_props(struct device_node *np, unsigned long mem_start) { struct address_range *adr; struct pci_reg_property *pci_addrs; - int i, l, *ip; + int i, l, *ip, ml; + struct pci_intr_map *imp; pci_addrs = (struct pci_reg_property *) get_property(np, "assigned-addresses", &l); @@ -645,6 +728,30 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start) mem_start += i * sizeof(struct address_range); } + /* + * If the pci host bridge has an interrupt-map property, + * look for our node in it. + */ + if (np->parent != 0 && pci_addrs != 0 + && (imp = (struct pci_intr_map *) + get_property(np->parent, "interrupt-map", &ml)) != 0 + && (ip = (int *) get_property(np, "interrupts", &l)) != 0) { + unsigned int busdevfn = pci_addrs[0].addr.a_hi & 0xffff00; + np->n_intrs = 0; + np->intrs = (struct interrupt_info *) mem_start; + for (i = 0; (ml -= sizeof(struct pci_intr_map)) >= 0; ++i) { + if (imp[i].addr.a_hi == busdevfn) { + np->intrs[np->n_intrs].line = imp[i].intr; + np->intrs[np->n_intrs].sense = 0; + ++np->n_intrs; + } + } + if (np->n_intrs == 0) + np->intrs = 0; + mem_start += np->n_intrs * sizeof(struct interrupt_info); + return mem_start; + } + ip = (int *) get_property(np, "AAPL,interrupts", &l); if (ip == 0) ip = (int *) get_property(np, "interrupts", &l); @@ -661,7 +768,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start) return mem_start; } -__openfirmware +__init static unsigned long interpret_dbdma_props(struct device_node *np, unsigned long mem_start) { @@ -710,7 +817,7 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start) return mem_start; } -__openfirmware +__init static unsigned long interpret_macio_props(struct device_node *np, unsigned long mem_start) { @@ -748,18 +855,28 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start) ip = (int *) get_property(np, "AAPL,interrupts", &l); if (ip != 0) { np->intrs = (struct interrupt_info *) mem_start; - np->n_intrs = l / (2 * sizeof(int)); - mem_start += np->n_intrs * sizeof(struct interrupt_info); - for (i = 0; i < np->n_intrs; ++i) { - np->intrs[i].line = openpic_to_irq(*ip++); - np->intrs[i].sense = *ip++; + if (_machine == _MACH_Pmac) { + /* for the iMac */ + np->n_intrs = l / sizeof(int); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 0; + } + } else { + /* CHRP machines */ + np->n_intrs = l / (2 * sizeof(int)); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = openpic_to_irq(*ip++); + np->intrs[i].sense = *ip++; + } } + mem_start += np->n_intrs * sizeof(struct interrupt_info); } return mem_start; } -__openfirmware +__init static unsigned long interpret_isa_props(struct device_node *np, unsigned long mem_start) { @@ -797,7 +914,7 @@ interpret_isa_props(struct device_node *np, unsigned long mem_start) return mem_start; } -__openfirmware +__init static unsigned long interpret_root_props(struct device_node *np, unsigned long mem_start) { @@ -876,6 +993,30 @@ find_type_devices(const char *type) return head; } +/* Checks if the given "compat" string matches one of the strings in + * the device's "compatible" property + */ +__openfirmware +int +device_is_compatible(struct device_node *device, const char *compat) +{ + const char* cp; + int cplen, l; + + cp = (char *) get_property(device, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strcasecmp(cp, compat) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} + /* * Construct and return a list of the device_nodes with a given type * and compatible property. @@ -885,15 +1026,13 @@ struct device_node * find_compatible_devices(const char *type, const char *compat) { struct device_node *head, **prevp, *np; - const char *cp; prevp = &head; for (np = allnodes; np != 0; np = np->allnext) { if (type != NULL && !(np->type != 0 && strcasecmp(np->type, type) == 0)) continue; - cp = (char *) get_property(np, "compatible", NULL); - if (cp != NULL && strcasecmp(cp, compat) == 0) { + if (device_is_compatible(np, compat)) { *prevp = np; prevp = &np->next; } @@ -951,6 +1090,7 @@ get_property(struct device_node *np, const char *name, int *lenp) return 0; } +#if 0 __openfirmware void print_properties(struct device_node *np) @@ -1001,7 +1141,9 @@ print_properties(struct device_node *np) } } } +#endif +/* this can be called after setup -- Cort */ __openfirmware int call_rtas(const char *service, int nargs, int nret, @@ -1038,7 +1180,7 @@ call_rtas(const char *service, int nargs, int nret, return u.words[nargs+3]; } -__openfirmware +__init void abort() { @@ -1048,3 +1190,563 @@ abort() #endif prom_exit(); } + +#define CALC_BASE(y) (bi->dispDeviceBase + bi->dispDeviceRect[0] * \ + (bi->dispDeviceDepth >> 3) + bi->dispDeviceRowBytes * (y)) + +__init +static void +clearscreen(void) +{ + unsigned long offset = reloc_offset(); + boot_infos_t* bi = PTRRELOC(RELOC(boot_infos)); + unsigned long *base = (unsigned long *)CALC_BASE(0); + unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) * + (bi->dispDeviceDepth >> 3)) >> 2; + int i,j; + + for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++) + { + unsigned long *ptr = base; + for(j=width; j; --j) + *(ptr++) = 0; + base += (bi->dispDeviceRowBytes >> 2); + } +} + +#ifdef CONFIG_BOOTX_TEXT + +__init +static void +scrollscreen(void) +{ + unsigned long offset = reloc_offset(); + boot_infos_t* bi = PTRRELOC(RELOC(boot_infos)); + unsigned long *src = (unsigned long *)CALC_BASE(16); + unsigned long *dst = (unsigned long *)CALC_BASE(0); + unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) * + (bi->dispDeviceDepth >> 3)) >> 2; + int i,j; + + for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1] - 16); i++) + { + unsigned long *src_ptr = src; + unsigned long *dst_ptr = dst; + for(j=width; j; --j) + *(dst_ptr++) = *(src_ptr++); + src += (bi->dispDeviceRowBytes >> 2); + dst += (bi->dispDeviceRowBytes >> 2); + } + for (i=0; i<16; i++) + { + unsigned long *dst_ptr = dst; + for(j=width; j; --j) + *(dst_ptr++) = 0; + dst += (bi->dispDeviceRowBytes >> 2); + } +} + +__init +static void +drawchar(char c) +{ + unsigned long offset = reloc_offset(); + + switch(c) + { + case '\r': RELOC(g_loc_X) = 0; break; + case '\n': RELOC(g_loc_X) = 0; RELOC(g_loc_Y)++; break; + default: + draw_byte(c, RELOC(g_loc_X)++, RELOC(g_loc_Y)); + if (RELOC(g_loc_X) >= RELOC(g_max_loc_X)) + { + RELOC(g_loc_X) = 0; + RELOC(g_loc_Y)++; + } + } + while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) + { + scrollscreen(); + RELOC(g_loc_Y)--; + } +} + +__init +static void +drawstring(const char *c) +{ + while(*c) + drawchar(*(c++)); +} + +__init +static void +draw_byte(unsigned char c, long locX, long locY) +{ + unsigned long offset = reloc_offset(); + boot_infos_t* bi = PTRRELOC(RELOC(boot_infos)); + unsigned char *base = bi->dispDeviceBase + + (bi->dispDeviceRowBytes * ((locY * 16) + bi->dispDeviceRect[1])) + + (bi->dispDeviceDepth >> 3) * ((locX * 8) + bi->dispDeviceRect[0]); + unsigned char *font = &RELOC(vga_font)[((unsigned long)c) * 16]; + + switch(bi->dispDeviceDepth) + { + case 32: + draw_byte_32(font, (unsigned long *)base); + break; + case 16: + draw_byte_16(font, (unsigned long *)base); + break; + case 8: + draw_byte_8(font, (unsigned long *)base); + break; + default: + break; + } +} + +__init +static unsigned long expand_bits_8[16] = { + 0x00000000, + 0x000000ff, + 0x0000ff00, + 0x0000ffff, + 0x00ff0000, + 0x00ff00ff, + 0x00ffff00, + 0x00ffffff, + 0xff000000, + 0xff0000ff, + 0xff00ff00, + 0xff00ffff, + 0xffff0000, + 0xffff00ff, + 0xffffff00, + 0xffffffff +}; + +__init +static unsigned long expand_bits_16[4] = { + 0x00000000, + 0x0000ffff, + 0xffff0000, + 0xffffffff +}; + + +__init +static void +draw_byte_32(unsigned char *font, unsigned long *base) +{ + unsigned long offset = reloc_offset(); + boot_infos_t* bi = PTRRELOC(RELOC(boot_infos)); + int l, bits; + int fg = 0xFFFFFFFFUL; + int bg = 0x00000000UL; + + + for (l = 0; l < 16; ++l) + { + bits = *font++; + base[0] = (-(bits >> 7) & fg) ^ bg; + base[1] = (-((bits >> 6) & 1) & fg) ^ bg; + base[2] = (-((bits >> 5) & 1) & fg) ^ bg; + base[3] = (-((bits >> 4) & 1) & fg) ^ bg; + base[4] = (-((bits >> 3) & 1) & fg) ^ bg; + base[5] = (-((bits >> 2) & 1) & fg) ^ bg; + base[6] = (-((bits >> 1) & 1) & fg) ^ bg; + base[7] = (-(bits & 1) & fg) ^ bg; + base = (unsigned long *) ((char *)base + bi->dispDeviceRowBytes); + } +} + +__init +static void +draw_byte_16(unsigned char *font, unsigned long *base) +{ + unsigned long offset = reloc_offset(); + boot_infos_t* bi = PTRRELOC(RELOC(boot_infos)); + int l, bits; + int fg = 0xFFFFFFFFUL; + int bg = 0x00000000UL; + unsigned long *eb = RELOC(expand_bits_16); + + for (l = 0; l < 16; ++l) + { + bits = *font++; + base[0] = (eb[bits >> 6] & fg) ^ bg; + base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg; + base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg; + base[3] = (eb[bits & 3] & fg) ^ bg; + base = (unsigned long *) ((char *)base + bi->dispDeviceRowBytes); + } +} + +__init +static void +draw_byte_8(unsigned char *font, unsigned long *base) +{ + unsigned long offset = reloc_offset(); + boot_infos_t* bi = PTRRELOC(RELOC(boot_infos)); + int l, bits; + int fg = 0x0F0F0F0FUL; + int bg = 0x00000000UL; + unsigned long *eb = RELOC(expand_bits_8); + + for (l = 0; l < 16; ++l) + { + bits = *font++; + base[0] = (eb[bits >> 4] & fg) ^ bg; + base[1] = (eb[bits & 0xf] & fg) ^ bg; + base = (unsigned long *) ((char *)base + bi->dispDeviceRowBytes); + } +} + +__init +static unsigned char vga_font[cmapsz] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, +0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, +0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, +0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, +0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, +0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, +0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, +0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, +0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, +0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, +0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, +0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, +0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, +0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, +0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, +0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, +0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, +0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, +0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, +0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, +0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, +0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, +0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, +0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, +0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, +0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, +0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, +0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, +0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, +0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, +0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, +0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, +0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, +0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, +0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, +0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, +0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, +0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, +0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, +0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, +0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, +0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, +0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, +0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, +0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, +0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, +0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, +0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, +0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, +0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, +0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, +0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, +0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, +0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, +0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, +0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, +0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, +0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, +0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, +0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, +0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, +0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, +0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, +0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, +0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, +0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, +0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, +0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, +0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, +0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, +0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, +0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, +0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, +0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, +0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, +0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, +0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, +0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, +0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, +0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, +0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, +0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, +0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, +0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, +0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, +0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, +0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, +0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, +0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, +0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, +0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, +0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, +0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, +0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, +0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, +0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, +}; + +#endif /* CONFIG_BOOTX_TEXT */ diff --git a/arch/ppc/kernel/residual.c b/arch/ppc/kernel/residual.c index 52db9debccb0..83333f660c25 100644 --- a/arch/ppc/kernel/residual.c +++ b/arch/ppc/kernel/residual.c @@ -1,5 +1,5 @@ /* - * $Id: residual.c,v 1.12 1998/08/27 23:15:56 paulus Exp $ + * $Id: residual.c,v 1.14 1998/10/11 17:38:10 cort Exp $ * * Code to deal with the PReP residual data. * @@ -49,7 +49,7 @@ #include -const char * PnP_BASE_TYPES[]= { +const char * PnP_BASE_TYPES[] __initdata = { "Reserved", "MassStorageDevice", "NetworkInterfaceController", @@ -65,7 +65,7 @@ const char * PnP_BASE_TYPES[]= { /* Device Sub Type Codes */ -const unsigned char * PnP_SUB_TYPES[] = { +const unsigned char * PnP_SUB_TYPES[] __initdata = { "\001\000SCSIController", "\001\001IDEController", "\001\002FloppyController", @@ -122,7 +122,7 @@ const unsigned char * PnP_SUB_TYPES[] = { /* Device Interface Type Codes */ -const unsigned char * PnP_INTERFACES[]= { +const unsigned char * PnP_INTERFACES[] __initdata = { "\000\000\000General", "\001\000\000GeneralSCSI", "\001\001\000GeneralIDE", @@ -240,7 +240,7 @@ const unsigned char * PnP_INTERFACES[]= { NULL }; -static const unsigned char *PnP_SUB_TYPE_STR(unsigned char BaseType, +static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType, unsigned char SubType) { const unsigned char ** s=PnP_SUB_TYPES; while (*s && !((*s)[0]==BaseType @@ -249,7 +249,7 @@ static const unsigned char *PnP_SUB_TYPE_STR(unsigned char BaseType, else return("Unknown !"); }; -static const unsigned char *PnP_INTERFACE_STR(unsigned char BaseType, +static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType, unsigned char SubType, unsigned char Interface) { const unsigned char ** s=PnP_INTERFACES; @@ -260,7 +260,7 @@ static const unsigned char *PnP_INTERFACE_STR(unsigned char BaseType, else return NULL; }; -static void printsmallvendor(PnP_TAG_PACKET *pkt, int size) { +static void __init printsmallvendor(PnP_TAG_PACKET *pkt, int size) { int i, c; char decomp[4]; #define p pkt->S14_Pack.S14_Data.S14_PPCPack @@ -285,7 +285,7 @@ static void printsmallvendor(PnP_TAG_PACKET *pkt, int size) { #undef p } -static void printsmallpacket(PnP_TAG_PACKET * pkt, int size) { +static void __init printsmallpacket(PnP_TAG_PACKET * pkt, int size) { static const unsigned char * intlevel[] = {"high", "low"}; static const unsigned char * intsense[] = {"edge", "level"}; @@ -352,7 +352,7 @@ static void printsmallpacket(PnP_TAG_PACKET * pkt, int size) { } } -static void printlargevendor(PnP_TAG_PACKET * pkt, int size) { +static void __init printlargevendor(PnP_TAG_PACKET * pkt, int size) { static const unsigned char * addrtype[] = {"I/O", "Memory", "System"}; static const unsigned char * inttype[] = {"8259", "MPIC", "RS6k BUID %d"}; static const unsigned char * convtype[] = {"Bus Memory", "Bus I/O", "DMA"}; @@ -462,7 +462,7 @@ static void printlargevendor(PnP_TAG_PACKET * pkt, int size) { } } -static void printlargepacket(PnP_TAG_PACKET * pkt, int size) { +static void __init printlargepacket(PnP_TAG_PACKET * pkt, int size) { switch (tag_large_item_name(pkt->S1_Pack.Tag)) { case LargeVendorItem: printlargevendor(pkt, size); @@ -473,7 +473,7 @@ static void printlargepacket(PnP_TAG_PACKET * pkt, int size) { break; } } -static void printpackets(PnP_TAG_PACKET * pkt, const char * cat) { +static void __init printpackets(PnP_TAG_PACKET * pkt, const char * cat) { if (pkt->S1_Pack.Tag== END_TAG) { printk(" No packets describing %s resources.\n", cat); return; @@ -494,7 +494,7 @@ static void printpackets(PnP_TAG_PACKET * pkt, const char * cat) { } while (pkt->S1_Pack.Tag != END_TAG); } -void print_residual_device_info(void) +void __init print_residual_device_info(void) { int i; PPC_DEVICE *dev; @@ -562,8 +562,8 @@ void print_residual_device_info(void) } - -static void printVPD(void) { +#if 0 +static void __init printVPD(void) { #define vpd res->VitalProductData int ps=vpd.PageSize, i, j; static const char* Usage[]={ @@ -628,7 +628,6 @@ static void printVPD(void) { /* * Spit out some info about residual data */ -#if 0 void print_residual_device_info(void) { int i; @@ -764,7 +763,7 @@ in this rarely used area we unencode and compare */ little endian in the heap, so we use two parameters to avoid writing two very similar functions */ -static int same_DevID(unsigned short vendor, +static int __init same_DevID(unsigned short vendor, unsigned short Number, char * str) { @@ -780,7 +779,7 @@ static int same_DevID(unsigned short vendor, return 0; } -PPC_DEVICE *residual_find_device(unsigned long BusMask, +PPC_DEVICE __init *residual_find_device(unsigned long BusMask, unsigned char * DevID, int BaseType, int SubType, @@ -803,7 +802,7 @@ PPC_DEVICE *residual_find_device(unsigned long BusMask, return 0; } -PPC_DEVICE *residual_find_device_id(unsigned long BusMask, +PPC_DEVICE __init *residual_find_device_id(unsigned long BusMask, unsigned short DevID, int BaseType, int SubType, @@ -844,7 +843,7 @@ PnP_TAG_PACKET *PnP_find_packet(unsigned char *p, return 0; /* not found */ } -PnP_TAG_PACKET *PnP_find_small_vendor_packet(unsigned char *p, +PnP_TAG_PACKET __init *PnP_find_small_vendor_packet(unsigned char *p, unsigned packet_type, int n) { @@ -858,7 +857,7 @@ PnP_TAG_PACKET *PnP_find_small_vendor_packet(unsigned char *p, return 0; /* not found */ } -PnP_TAG_PACKET *PnP_find_large_vendor_packet(unsigned char *p, +PnP_TAG_PACKET __init *PnP_find_large_vendor_packet(unsigned char *p, unsigned packet_type, int n) { diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index a3b0dd4a38d3..706c1dde2f2a 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -1,5 +1,5 @@ /* - * $Id: setup.c,v 1.103 1998/09/18 09:14:56 paulus Exp $ + * $Id: setup.c,v 1.117 1998/11/09 19:55:53 geert Exp $ * Common prep/pmac/chrp boot and setup code. */ @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef CONFIG_MBX #include #endif @@ -131,9 +132,7 @@ void machine_restart(char *cmd) cuda_poll(); break; case ADB_VIAPMU: - pmu_request(&req, NULL, 1, PMU_RESET); - for (;;) - pmu_poll(); + pmu_restart(); break; default: } @@ -206,10 +205,7 @@ void machine_power_off(void) cuda_poll(); break; case ADB_VIAPMU: - pmu_request(&req, NULL, 5, PMU_SHUTDOWN, - 'M', 'A', 'T', 'T'); - for (;;) - pmu_poll(); + pmu_shutdown(); break; default: } @@ -250,9 +246,11 @@ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) { #if !defined(CONFIG_MBX) && !defined(CONFIG_APUS) switch (_machine) { +#if defined(CONFIG_BLK_DEV_IDE_PMAC) case _MACH_Pmac: - pmac_ide_init_hwif_ports(p,base,irq); + pmac_ide_init_hwif_ports(p,base,irq); break; +#endif case _MACH_chrp: chrp_ide_init_hwif_ports(p,base,irq); break; @@ -267,68 +265,31 @@ EXPORT_SYMBOL(ide_init_hwif_ports); unsigned long cpu_temp(void) { -#if 0 - unsigned long i, temp, thrm1, dir; - int sanity; + unsigned char thres = 0; - /* - * setup thrm3 - need to give TAU at least 20us - * to do the compare so assume a 300MHz clock. - * We need 300*20 ticks then. - * -- Cort - */ - asm("mtspr 1020, %1\n\t" - "mtspr 1021, %1\n\t" - "mtspr 1022, %0\n\t":: - "r" ( ((300*20)<<18) | THRM3_E), "r" (0) ); - -#if 0 - for ( i = 127 ; i >= 0 ; i-- ) - { - asm("mtspr 1020, %0\n\t":: - "r" (THRM1_TID|THRM1_V|(i<<2)) ); - /* check value */ - while ( !( thrm1 & THRM1_TIV) ) - asm("mfspr %0, 1020 \n\t": "=r" (thrm1) ); - if ( thrm1 & THRM1_TIN ) - { - printk("tin set: %x tiv %x\n", thrm1,thrm1&THRM1_TIV); - goto out; - } - - } -#endif #if 0 - i = 32; /* increment */ - dir = 1; /* direction we're checking 0=up 1=down */ - temp = 64; /* threshold checking against */ - while ( i ) - { - _set_THRM1((1<<29) | THRM1_V | (temp<<2) ); - printk("checking %d in dir %d thrm set to %x/%x\n", temp,dir, - ( (1<<29) | THRM1_V | (temp<<2)),_get_THRM1()); - /* check value */ - sanity = 0x0fffffff; - while ( (!( thrm1 & THRM1_TIV)) && (sanity--) ) - thrm1 = _get_THRM1(); - /*asm("mfspr %0, 1020 \n\t": "=r" (thrm1) );*/ - if ( ! sanity || sanity==0xffffffff ) printk("no sanity\n"); - /* temp is not in that direction */ - if ( !(thrm1 & THRM1_TIN) ) - { - printk("not in that dir thrm1 %x\n",thrm1); - if ( dir == 0 ) dir = 1; - else dir = 0; - } - if ( dir ) temp -= i; - else temp += i; - i /= 2; - } - asm("mtspr 1020, %0\n\t" - "mtspr 1022, %0\n\t" ::"r" (0) ); + /* disable thrm2 */ + _set_THRM2( 0 ); + /* threshold 0 C, tid: exceeding threshold, tie: don't generate interrupt */ + _set_THRM1( THRM1_V ); + + /* we need 20us to do the compare - assume 300MHz processor clock */ + _set_THRM3(0); + _set_THRM3(THRM3_E | (300*30)<<18 ); + + udelay(100); + /* wait for the compare to complete */ + /*while ( !(_get_THRM1() & THRM1_TIV) ) ;*/ + if ( !(_get_THRM1() & THRM1_TIV) ) + printk("no tiv\n"); + if ( _get_THRM1() & THRM1_TIN ) + printk("crossed\n"); + /* turn everything off */ + _set_THRM3(0); + _set_THRM1(0); #endif -#endif - return 0; + + return thres; } int get_cpuinfo(char *buffer) @@ -342,12 +303,11 @@ int get_cpuinfo(char *buffer) unsigned long i; #ifdef __SMP__ - extern unsigned long cpu_present_map; - extern struct cpuinfo_PPC cpu_data[NR_CPUS]; +#define CPU_PRESENT(x) (cpu_callin_map[(x)]) #define GET_PVR ((long int)(cpu_data[i].pvr)) #define CD(x) (cpu_data[i].x) #else -#define cpu_present_map 1L +#define CPU_PRESENT(x) ((x)==0) #define smp_num_cpus 1 #define GET_PVR ((long int)_get_PVR()) #define CD(x) (x) @@ -355,7 +315,7 @@ int get_cpuinfo(char *buffer) for ( i = 0; i < smp_num_cpus ; i++ ) { - if ( ! ( cpu_present_map & (1< *memory_end_p) - { - printk("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_end,*memory_end_p); - initrd_start = 0; - } - } -#endif - #ifdef CONFIG_MBX mbx_setup_arch(memory_start_p,memory_end_p); #else /* CONFIG_MBX */ diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index f622623ae41b..3ffb7981e9c2 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -1,7 +1,7 @@ /* * linux/arch/ppc/kernel/signal.c * - * $Id: signal.c,v 1.20 1998/09/28 16:47:09 cort Exp $ + * $Id: signal.c,v 1.21 1998/10/22 19:37:49 paulus Exp $ * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -245,7 +245,7 @@ int sys_sigreturn(struct pt_regs *regs) goto badframe; sr = (struct sigregs *) sigctx.regs; regs->gpr[3] = ret = sigctx.signal; - regs->gpr[4] = (unsigned long) sr; + regs->gpr[4] = (unsigned long) sc; regs->link = (unsigned long) &sr->tramp; regs->nip = sigctx.handler; @@ -293,7 +293,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame, || get_user(regs->gpr[3], &sc->signal)) goto badframe; regs->gpr[1] = newsp; - regs->gpr[4] = (unsigned long) frame; + regs->gpr[4] = (unsigned long) sc; regs->link = (unsigned long) frame->tramp; return; diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index f3c71ccd1a27..75445925f83c 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -1,5 +1,5 @@ /* - * $Id: smp.c,v 1.33 1998/09/25 04:32:30 cort Exp $ + * $Id: smp.c,v 1.36 1998/10/08 01:17:48 cort Exp $ * * Smp support for ppc. * @@ -35,24 +35,20 @@ int smp_threads_ready = 0; volatile int smp_commenced = 0; int smp_num_cpus = 1; -unsigned long cpu_present_map = 0; -volatile int cpu_number_map[NR_CPUS]; -volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; -volatile int __cpu_logical_map[NR_CPUS]; -static unsigned char boot_cpu_id = 0; struct cpuinfo_PPC cpu_data[NR_CPUS]; struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 }; volatile unsigned char active_kernel_processor = NO_PROC_ID; /* Processor holding kernel spinlock */ volatile unsigned long ipi_count; spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; - unsigned int prof_multiplier[NR_CPUS]; unsigned int prof_counter[NR_CPUS]; - int first_cpu_booted = 0; -int start_secondary(void *); +/* all cpu mappings are 1-1 -- Cort */ +int cpu_number_map[NR_CPUS] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,}; +volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; +int start_secondary(void *); extern int cpu_idle(void *unused); void smp_local_timer_interrupt(struct pt_regs * regs) @@ -60,7 +56,6 @@ void smp_local_timer_interrupt(struct pt_regs * regs) int cpu = smp_processor_id(); extern void update_one_process(struct task_struct *,unsigned long, unsigned long,unsigned long,int); - if (!--prof_counter[cpu]) { int user=0,system=0; struct task_struct * p = current; @@ -106,7 +101,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs) * Right now it only works for stop cpu's but will be setup * later for more general message passing. * - * As it is now, if we're sending two message as the same time + * As it is now, if we're sending two message at the same time * we have race conditions. I avoided doing locks here since * all that works right now is the stop cpu message. * @@ -117,17 +112,25 @@ void smp_message_recv(void) { int msg = smp_message[smp_processor_id()]; - printk("SMP %d: smp_message_recv() msg %x\n", smp_processor_id(),msg); + /* clear interrupt */ + *(volatile unsigned long *)(0xf80000c0) = ~0L; + eieio(); /* make sure msg is for us */ if ( msg == -1 ) return; + ipi_count++; + /*printk("SMP %d: smp_message_recv() msg %x\n", smp_processor_id(),msg);*/ + switch( msg ) { case MSG_STOP_CPU: __cli(); while (1) ; break; + case MSG_RESCHEDULE: + current->need_resched = 1; + break; case 0xf0f0: /* syncing time bases - just return */ break; default: @@ -141,19 +144,17 @@ void smp_message_recv(void) void smp_send_reschedule(int cpu) { - /* for now, nothing */ + smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0); } - spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED; void smp_message_pass(int target, int msg, unsigned long data, int wait) { - printk("SMP %d: sending smp message\n", current->processor); - - spin_lock(&mesg_pass_lock); if ( _machine != _MACH_Pmac ) return; - + /*printk("SMP %d: sending smp message\n", current->processor);*/ +if (smp_processor_id() ) printk("pass from cpu 1\n"); + spin_lock(&mesg_pass_lock); #define OTHER (~smp_processor_id() & 1) switch( target ) @@ -169,9 +170,10 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) break; } /* interrupt secondary processor */ - /**(volatile unsigned long *)(0xf80000c0) = 0xffffffff; - eieio();*/ - *(volatile unsigned long *)(0xf80000c0) = 0; + *(volatile unsigned long *)(0xf80000c0) = ~0L; + eieio(); + *(volatile unsigned long *)(0xf80000c0) = 0L; + eieio(); /* interrupt primary */ /**(volatile unsigned long *)(0xf3019000);*/ spin_unlock(&mesg_pass_lock); @@ -180,6 +182,7 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) __initfunc(void smp_boot_cpus(void)) { extern struct task_struct *current_set[NR_CPUS]; + extern void __secondary_start(void); int i; struct task_struct *p; @@ -189,21 +192,14 @@ __initfunc(void smp_boot_cpus(void)) dcbf(&first_cpu_booted); for (i = 0; i < NR_CPUS; i++) { - cpu_number_map[i] = -1; prof_counter[i] = 1; prof_multiplier[i] = 1; } - - cpu_present_map = 0; - for(i=0; i < NR_CPUS; i++) - __cpu_logical_map[i] = -1; - smp_store_cpu_info(boot_cpu_id); - active_kernel_processor = boot_cpu_id; - current->processor = boot_cpu_id; - cpu_present_map |= 1; - cpu_number_map[boot_cpu_id] = 0; - __cpu_logical_map[0] = boot_cpu_id; + cpu_callin_map[0] = 1; + smp_store_cpu_info(0); + active_kernel_processor = 0; + current->processor = 0; if ( _machine != _MACH_Pmac ) { @@ -211,10 +207,6 @@ __initfunc(void smp_boot_cpus(void)) return; } - /* assume a 2nd processor for now */ - cpu_present_map |= (1 << 1); - smp_num_cpus = 2; - /* create a process for second processor */ kernel_thread(start_secondary, NULL, CLONE_PID); p = task[1]; @@ -222,15 +214,16 @@ __initfunc(void smp_boot_cpus(void)) panic("No idle task for secondary processor\n"); p->processor = 1; current_set[1] = p; + /* need to flush here since secondary bat's aren't setup */ dcbf((void *)¤t_set[1]); - /* setup entry point of secondary processor */ - /* *(volatile unsigned long *)(0xf2800000) - = (unsigned long)secondary_entry-KERNELBASE;*/ - *(volatile unsigned long *)(0xf2800000) = 0x100; + *(volatile unsigned long *)(0xf2800000) = + (unsigned long)__secondary_start-KERNELBASE; eieio(); /* interrupt secondary to begin executing code */ + *(volatile unsigned long *)(0xf80000c0) = ~0L; + eieio(); *(volatile unsigned long *)(0xf80000c0) = 0L; eieio(); /* @@ -241,24 +234,21 @@ __initfunc(void smp_boot_cpus(void)) */ for ( i = 1000; i && !cpu_callin_map[1] ; i-- ) udelay(100); - + if(cpu_callin_map[1]) { - cpu_number_map[1] = 1; - __cpu_logical_map[i] = 1; - printk("Processor 1 found.\n"); - + printk("Processor %d found.\n", smp_num_cpus); + smp_num_cpus++; #if 0 /* this sync's the decr's, but we don't want this now -- Cort */ set_dec(decrementer_count); #endif - /* interrupt secondary to start decr's on both cpus */ - smp_message_pass(1,0xf0f0, 0, 0); - /* interrupt secondary to begin executing code */ - /**(volatile unsigned long *)(0xf80000c0) = 0L; - eieio();*/ } else { - smp_num_cpus--; - printk("Processor %d is stuck.\n", 1); + printk("Processor %d is stuck. \n", smp_num_cpus); } + /* reset the entry point so if we get another intr we won't + * try to startup again */ + *(volatile unsigned long *)(0xf2800000) = 0x100; + /* send interrupt to other processors to start decr's on all cpus */ + smp_message_pass(1,0xf0f0, 0, 0); } __initfunc(void smp_commence(void)) @@ -278,7 +268,7 @@ __initfunc(void initialize_secondary(void)) } /* Activate a secondary processor. */ -__initfunc(int start_secondary(void *unused)) +asmlinkage int __init start_secondary(void *unused) { printk("SMP %d: start_secondary()\n",current->processor); smp_callin(); @@ -288,16 +278,14 @@ __initfunc(int start_secondary(void *unused)) __initfunc(void smp_callin(void)) { printk("SMP %d: smp_callin()\n",current->processor); - smp_store_cpu_info(1); + smp_store_cpu_info(current->processor); set_dec(decrementer_count); current->mm->mmap->vm_page_prot = PAGE_SHARED; current->mm->mmap->vm_start = PAGE_OFFSET; current->mm->mmap->vm_end = init_task.mm->mmap->vm_end; - - /* assume we're just the secondary processor for now */ - cpu_callin_map[1] = 1; + cpu_callin_map[current->processor] = current->processor; while(!smp_commenced) barrier(); __sti(); @@ -317,6 +305,7 @@ __initfunc(void smp_store_cpu_info(int id)) { struct cpuinfo_PPC *c = &cpu_data[id]; + /* assume bogomips are same for everything */ c->loops_per_sec = loops_per_sec; c->pvr = _get_PVR(); } diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 0857c263363e..8bada0e6961a 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -1,5 +1,5 @@ /* - * $Id: time.c,v 1.35 1998/07/24 11:05:47 geert Exp $ + * $Id: time.c,v 1.36 1998/10/10 12:16:08 geert Exp $ * Common time routines among all ppc machines. * * Written by Cort Dougan (cort@cs.nmt.edu) to merge @@ -106,7 +106,12 @@ void timer_interrupt(struct pt_regs * regs) #ifdef __SMP__ smp_local_timer_interrupt(regs); #endif - +#ifdef CONFIG_APUS + { + extern void apus_heartbeat (void); + apus_heartbeat (); + } +#endif hardirq_exit(cpu); /* restore the HID0 in case dcache was off - see idle.c * this hack should leave for a better solution -- Cort */ diff --git a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c index 0bb06f8084e3..073e7076cc13 100644 --- a/arch/ppc/lib/locks.c +++ b/arch/ppc/lib/locks.c @@ -1,5 +1,5 @@ /* - * $Id: locks.c,v 1.18 1998/07/28 03:50:27 cort Exp $ + * $Id: locks.c,v 1.20 1998/10/08 01:17:32 cort Exp $ * * Locks for smp ppc * @@ -18,13 +18,13 @@ #define DEBUG_LOCKS 1 #undef INIT_STUCK -#define INIT_STUCK 10000 +#define INIT_STUCK 0xffffffff void _spin_lock(spinlock_t *lock) { int cpu = smp_processor_id(); #ifdef DEBUG_LOCKS - int stuck = INIT_STUCK; + unsigned int stuck = INIT_STUCK; #endif /* DEBUG_LOCKS */ /* try expensive atomic load/store to get lock */ while((unsigned long )xchg_u32((void *)&lock->lock,0xffffffff)) { @@ -67,13 +67,13 @@ int spin_trylock(spinlock_t *lock) void _spin_unlock(spinlock_t *lp) { #ifdef DEBUG_LOCKS - if ( !lp->lock ) - panic("_spin_unlock(%p): no lock cpu %d %s/%d\n", lp, - smp_processor_id(),current->comm,current->pid); + if ( !lp->lock ) + printk("_spin_unlock(%p): no lock cpu %d %s/%d\n", lp, + smp_processor_id(),current->comm,current->pid); if ( lp->owner_cpu != smp_processor_id() ) - panic("_spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %lx\n", - lp, smp_processor_id(), (int)lp->owner_cpu, - lp->owner_pc,lp->lock); + printk("_spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %lx\n", + lp, smp_processor_id(), (int)lp->owner_cpu, + lp->owner_pc,lp->lock); #endif /* DEBUG_LOCKS */ lp->owner_pc = lp->owner_cpu = 0; eieio(); diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index 9f4b287a7d54..b45f4e6f4c97 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -38,7 +38,7 @@ extern void (*debugger)(struct pt_regs *); extern void (*debugger_fault_handler)(struct pt_regs *); extern int (*debugger_dabr_match)(struct pt_regs *); -int debugger_kernel_faults = 0; +int debugger_kernel_faults = 1; #endif unsigned long htab_reloads = 0; /* updated by head.S:hash_page() */ diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 3f44bab8ed33..44104fd4e26f 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -1,5 +1,5 @@ /* - * $Id: init.c,v 1.123 1998/09/19 19:03:55 geert Exp $ + * $Id: init.c,v 1.130 1998/11/10 10:09:20 paulus Exp $ * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -114,7 +114,8 @@ struct batrange { /* stores address ranges mapped by BATs */ * (i.e. page tables) instead of the bats. * -- Cort */ -#undef MAP_RAM_WITH_SEGREGS 1 +int __map_without_bats = 0; + /* optimization for 603 to load the tlb directly from the linux table -- Cort */ #define NO_RELOAD_HTAB 1 /* change in kernel/head.S too! */ @@ -243,20 +244,24 @@ void show_mem(void) printk("%3d ", p->processor); if ( (p->processor != NO_PROC_ID) && (p == current_set[p->processor]) ) - + { + iscur = 1; + printk("current"); + } #else if ( p == current ) -#endif /* __SMP__ */ { iscur = 1; printk("current"); } + if ( p == last_task_used_math ) { if ( iscur ) printk(","); printk("last math"); } +#endif /* __SMP__ */ printk("\n"); } } @@ -677,18 +682,21 @@ __initfunc(static void sort_mem_pieces(struct mem_pieces *mp)) __initfunc(static void coalesce_mem_pieces(struct mem_pieces *mp)) { - unsigned long a, e; + unsigned long a, s, ns; int i, j, d; d = 0; for (i = 0; i < mp->n_regions; i = j) { a = mp->regions[i].address; - e = a + mp->regions[i].size; + s = mp->regions[i].size; for (j = i + 1; j < mp->n_regions - && mp->regions[j].address <= e; ++j) - e = mp->regions[j].address + mp->regions[j].size; + && mp->regions[j].address - a <= s; ++j) { + ns = mp->regions[j].address + mp->regions[j].size - a; + if (ns > s) + s = ns; + } mp->regions[d].address = a; - mp->regions[d].size = e - a; + mp->regions[d].size = s; ++d; } mp->n_regions = d; @@ -800,28 +808,41 @@ __initfunc(static void mapin_ram(void)) int i; unsigned long v, p, s, f; #ifndef CONFIG_8xx - unsigned long tot, mem_base, bl, done; - -#ifndef MAP_RAM_WITH_SEGREGS - /* Set up BAT2 and if necessary BAT3 to cover RAM. */ - mem_base = __pa(KERNELBASE); - tot = (unsigned long)end_of_DRAM - KERNELBASE; - for (bl = 128<<10; bl < 256<<20; bl <<= 1) { - if (bl * 2 > tot) - break; - } - setbat(2, KERNELBASE, mem_base, bl, RAM_PAGE); - done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; - if (done < tot) { - /* use BAT3 to cover a bit more */ - tot -= done; - for (bl = 128<<10; bl < 256<<20; bl <<= 1) + if (!__map_without_bats) { + unsigned long tot, mem_base, bl, done; + unsigned long max_size = (256<<20); + unsigned long align; + + /* Set up BAT2 and if necessary BAT3 to cover RAM. */ + mem_base = __pa(KERNELBASE); + + /* Make sure we don't map a block larger than the + smallest alignment of the physical address. */ + /* alignment of mem_base */ + align = ~(mem_base-1) & mem_base; + /* set BAT block size to MIN(max_size, align) */ + if (align && align < max_size) + max_size = align; + + tot = (unsigned long)end_of_DRAM - KERNELBASE; + for (bl = 128<<10; bl < max_size; bl <<= 1) { if (bl * 2 > tot) break; - setbat(3, KERNELBASE+done, mem_base+done, bl, RAM_PAGE); + } + + setbat(2, KERNELBASE, mem_base, bl, RAM_PAGE); + done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; + if (done < tot) { + /* use BAT3 to cover a bit more */ + tot -= done; + for (bl = 128<<10; bl < max_size; bl <<= 1) + if (bl * 2 > tot) + break; + setbat(3, KERNELBASE+done, mem_base+done, bl, + RAM_PAGE); + } } -#endif v = KERNELBASE; for (i = 0; i < phys_mem.n_regions; ++i) { @@ -897,7 +918,10 @@ __initfunc(void free_initmem(void)) switch (_machine) { case _MACH_Pmac: + FREESEC(__prep_begin,__prep_end,num_prep_pages); + break; case _MACH_chrp: + FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); FREESEC(__prep_begin,__prep_end,num_prep_pages); break; case _MACH_prep: @@ -965,8 +989,14 @@ __initfunc(void MMU_init(void)) setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE); break; case _MACH_Pmac: - setbat(0, 0xf3000000, 0xf3000000, 0x100000, IO_PAGE); - ioremap_base = 0xf0000000; + { + unsigned long base = 0xf3000000; + struct device_node *macio = find_devices("mac-io"); + if (macio && macio->n_addrs) + base = macio->addrs[0].address; + setbat(0, base, base, 0x100000, IO_PAGE); + ioremap_base = 0xf0000000; + } break; case _MACH_apus: /* Map PPC exception vectors. */ diff --git a/arch/ppc/pmac_defconfig b/arch/ppc/pmac_defconfig index eeb7db2791d8..ae1303bb4813 100644 --- a/arch/ppc/pmac_defconfig +++ b/arch/ppc/pmac_defconfig @@ -35,16 +35,20 @@ CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m # CONFIG_BINFMT_JAVA is not set # CONFIG_PARPORT is not set +# CONFIG_VGA_CONSOLE is not set CONFIG_FB=y CONFIG_FB_COMPAT_XPMAC=y CONFIG_PMAC_PBOOK=y CONFIG_MAC_KEYBOARD=y CONFIG_MAC_FLOPPY=y CONFIG_MAC_SERIAL=y -CONFIG_MACMOUSE=y +CONFIG_ADBMOUSE=y +CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_PROC_DEVICETREE=y # CONFIG_KGDB is not set -CONFIG_XMON=y +# CONFIG_XMON is not set +# CONFIG_TOTALMP is not set +CONFIG_BOOTX_TEXT=y # # Plug and Play support @@ -70,6 +74,10 @@ CONFIG_BLK_DEV_IDEFLOPPY=y # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_IDEPCI is not set # CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_PMAC_IDEDMA_AUTO=y # CONFIG_IDE_CHIPSETS is not set # @@ -159,7 +167,7 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA152X is not set # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set -CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC7XXX=y # CONFIG_OVERRIDE_CMDS is not set CONFIG_AIC7XXX_PROC_STATS=y CONFIG_AIC7XXX_RESET_DELAY=15 @@ -216,23 +224,26 @@ CONFIG_NET_EISA=y # CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set -CONFIG_DE4X5=m +CONFIG_DE4X5=y CONFIG_DEC_ELCP=m # CONFIG_DGRS is not set # CONFIG_EEXPRESS_PRO100 is not set # CONFIG_LNE390 is not set +# CONFIG_NE3210 is not set # CONFIG_NE2K_PCI is not set # CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set # CONFIG_ES3210 is not set # CONFIG_EPIC100 is not set # CONFIG_ZNET is not set # CONFIG_NET_POCKET is not set # CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_DLCI is not set # CONFIG_LTPC is not set # CONFIG_COPS is not set # CONFIG_IPDDP is not set -CONFIG_PPP=m +CONFIG_PPP=y # # CCP compressors for PPP are only built as modules. @@ -241,6 +252,7 @@ CONFIG_PPP=m # CONFIG_NET_RADIO is not set # CONFIG_TR is not set # CONFIG_SHAPER is not set +# CONFIG_HOSTESS_SV11 is not set # # Amateur Radio support @@ -264,11 +276,12 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_FB_OF=y CONFIG_FB_CONTROL=y CONFIG_FB_PLATINUM=y +CONFIG_FB_VALKYRIE=y CONFIG_FB_ATY=y CONFIG_FB_IMSTT=y CONFIG_FB_CT65550=y # CONFIG_FB_S3TRIO is not set -# CONFIG_FB_VGA is not set +# CONFIG_FB_MATROX is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -293,8 +306,9 @@ CONFIG_VT_CONSOLE=y CONFIG_SERIAL=m # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_MOUSE is not set -# CONFIG_UMISC is not set # CONFIG_QIC02_TAPE is not set # CONFIG_WATCHDOG is not set # CONFIG_RTC is not set @@ -322,6 +336,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_FS=y CONFIG_NFS_FS=y CONFIG_NFSD=y +# CONFIG_NFSD_SUN is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_CODA_FS is not set @@ -330,12 +345,16 @@ CONFIG_LOCKD=y # CONFIG_NTFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=m +CONFIG_HFS_FS=y # CONFIG_ROMFS_FS is not set CONFIG_AUTOFS_FS=y # CONFIG_UFS_FS is not set -# CONFIG_ADFS_FS is not set +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_SMD_DISKLABEL is not set +# CONFIG_SOLARIS_X86_PARTITION is not set CONFIG_DEVPTS_FS=y +# CONFIG_ADFS_FS is not set +# CONFIG_QNX4FS_FS is not set CONFIG_MAC_PARTITION=y CONFIG_NLS=y @@ -374,3 +393,9 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_SOUND=y CONFIG_DMASOUND=y +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_OSS is not set diff --git a/arch/ppc/prep_defconfig b/arch/ppc/prep_defconfig index f503c4942638..41db35a4a4a9 100644 --- a/arch/ppc/prep_defconfig +++ b/arch/ppc/prep_defconfig @@ -41,7 +41,7 @@ CONFIG_VGA_CONSOLE=y # CONFIG_MAC_KEYBOARD is not set # CONFIG_MAC_FLOPPY is not set # CONFIG_MAC_SERIAL is not set -# CONFIG_MACMOUSE is not set +# CONFIG_ADBMOUSE is not set # CONFIG_PROC_DEVICETREE is not set # CONFIG_KGDB is not set # CONFIG_XMON is not set diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index a7631741e0f1..cc97d18ddbde 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -114,7 +114,7 @@ #define FD_HD_3 0x55555555 /* high-density 3.5" (1760K) drive */ #define FD_DD_5 0xaaaaaaaa /* double-density 5.25" (440K) drive */ -static long int fd_def_df0 = 0; /* default for df0 if it doesn't identify */ +static long int fd_def_df0 = FD_DD_3; /* default for df0 if it doesn't identify */ MODULE_PARM(fd_def_df0,"l"); @@ -1859,20 +1859,6 @@ __initfunc(int amiga_floppy_init(void)) blksize_size[MAJOR_NR] = floppy_blocksizes; blk_size[MAJOR_NR] = floppy_sizes; - - #if 0 /* Doesn't seem to be correct */ - if (fd_def_df0==0) { - if ((amiga.model == AMI_3000) || (amiga.model == AMI_3000T) || - (amiga.model == AMI_3000PLUS) || (amiga.model == AMI_4000)) - fd_def_df0=FD_HD_3; - else - fd_def_df0=FD_DD_3; - } - #else - /* Now we hope that every HD drive will identify itself correctly */ - fd_def_df0 = FD_DD_3; - #endif - for (i = 0; i < 128; i++) mfmdecode[i]=255; for (i = 0; i < 16; i++) diff --git a/drivers/block/ide-pmac.c b/drivers/block/ide-pmac.c index cb8b13e06321..f504cb9c2fe4 100644 --- a/drivers/block/ide-pmac.c +++ b/drivers/block/ide-pmac.c @@ -25,10 +25,13 @@ #include #include #include +#include #include "ide.h" ide_ioreg_t pmac_ide_regbase[MAX_HWIFS]; int pmac_ide_irq[MAX_HWIFS]; +int pmac_ide_count; +struct device_node *pmac_ide_node[MAX_HWIFS]; #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC #define MAX_DCMDS 256 /* allow up to 256 DBDMA commands per xfer */ @@ -45,15 +48,18 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, int wr); void pmac_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq) { - int i; + int i, r; *p = 0; if (base == 0) return; - if (base == mb_cd_base && !check_media_bay(MB_CD)) { - mb_cd_index = -1; + /* we check only for -EINVAL meaning that we have found a matching + bay but with the wrong device type */ + + r = check_media_bay_by_base(base, MB_CD); + if (r == -EINVAL) return; - } + for (i = 0; i < 8; ++i) *p++ = base + i * 0x10; *p = base + 0x160; @@ -93,8 +99,8 @@ pmac_ide_probe(void)) /* Move removable devices such as the media-bay CDROM on the PB3400 to the end of the list. */ for (; p != NULL; p = p->next) { - if (p->parent && p->parent->name - && strcasecmp(p->parent->name, "media-bay") == 0) { + if (p->parent && p->parent->type + && strcasecmp(p->parent->type, "media-bay") == 0) { *rp = p; rp = &p->next; } else { @@ -111,7 +117,13 @@ pmac_ide_probe(void)) np->full_name); continue; } + base = (unsigned long) ioremap(np->addrs[0].address, 0x200); + + /* XXX This is bogus. Should be fixed in the registry by checking + the kind of host interrupt controller, a bit like gatwick + fixes in irq.c + */ if (np->n_intrs == 0) { printk("ide: no intrs for device %s, using 13\n", np->full_name); @@ -121,13 +133,13 @@ pmac_ide_probe(void)) } pmac_ide_regbase[i] = base; pmac_ide_irq[i] = irq; + pmac_ide_node[i] = np; if (np->parent && np->parent->name && strcasecmp(np->parent->name, "media-bay") == 0) { - mb_cd_index = i; - mb_cd_base = base; - mb_cd_irq = irq; - } + media_bay_set_ide_infos(np->parent,base,irq,i); + } else + feature_set(np, FEATURE_IDE_enable); hwif = &ide_hwifs[i]; pmac_ide_init_hwif_ports(hwif->io_ports, base, &hwif->irq); @@ -143,6 +155,7 @@ pmac_ide_probe(void)) ++i; } + pmac_ide_count = i; } #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC diff --git a/drivers/block/sl82c105.c b/drivers/block/sl82c105.c index 39b62fddd5a8..6c1d12cb948b 100644 --- a/drivers/block/sl82c105.c +++ b/drivers/block/sl82c105.c @@ -14,11 +14,6 @@ #include "ide.h" #include "ide_modes.h" -unsigned int chrp_ide_irq = 0; -int chrp_ide_ports_known = 0; -ide_ioreg_t chrp_ide_regbase[MAX_HWIFS]; -ide_ioreg_t chrp_idedma_regbase; - void ide_init_sl82c105(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -37,37 +32,3 @@ void ide_init_sl82c105(ide_hwif_t *hwif) printk("IDE control/status register: %08x\n",t32); pci_write_config_dword(dev, 0x40, 0x10ff08a1); } - -/* nobody ever calls these.. ?? -mlord - * - * Yes somebody certainly does, check asm-ppc/ide.h for the place. -DaveM - */ -void chrp_ide_probe(void) { - - struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, NULL); - - chrp_ide_ports_known = 1; - - if(pdev) { - chrp_ide_regbase[0]=pdev->base_address[0] & - PCI_BASE_ADDRESS_IO_MASK; - chrp_ide_regbase[1]=pdev->base_address[2] & - PCI_BASE_ADDRESS_IO_MASK; - chrp_idedma_regbase=pdev->base_address[4] & - PCI_BASE_ADDRESS_IO_MASK; - chrp_ide_irq=pdev->irq; - } -} - - -void chrp_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) -{ - ide_ioreg_t port = base; - int i = 8; - - while (i--) - *p++ = port++; - *p++ = port; - if (irq != NULL) - *irq = chrp_ide_irq; -} diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index fad28716ce3c..247db08d66da 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -22,12 +22,15 @@ #include #include #include +#include #define MAJOR_NR FLOPPY_MAJOR #include -static int floppy_blocksizes[2] = {512}; -static int floppy_sizes[2] = {2880}; +static int floppy_blocksizes[2] = {512,512}; +static int floppy_sizes[2] = {2880,2880}; + +#define MAX_FLOPPIES 2 enum swim_state { idle, @@ -139,11 +142,12 @@ struct floppy_state { int ejected; struct wait_queue *wait; int wanted; - int in_media_bay; + struct device_node* media_bay; /* NULL when not in bay */ char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)]; }; -static struct floppy_state floppy_states[1]; +static struct floppy_state floppy_states[MAX_FLOPPIES]; +static int floppy_count = 0; static unsigned short write_preamble[] = { 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, /* gap field */ @@ -175,7 +179,7 @@ static void scan_timeout(unsigned long data); static void seek_timeout(unsigned long data); static void xfer_timeout(unsigned long data); static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs); +/*static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs);*/ static int grab_drive(struct floppy_state *fs, enum swim_state state, int interruptible); static void release_drive(struct floppy_state *fs); @@ -190,6 +194,7 @@ static ssize_t floppy_write(struct file *filp, const char *buf, size_t count, loff_t *ppos); static int floppy_check_change(kdev_t dev); static int floppy_revalidate(kdev_t dev); +static int swim3_add_device(struct device_node *swims); int swim3_init(void); #define IOCTL_MODE_BIT 8 @@ -212,11 +217,11 @@ static void swim3_action(struct floppy_state *fs, int action) volatile struct swim3 *sw = fs->swim3; swim3_select(fs, action); - udelay(1); + udelay(10); sw->select |= LSTRB; eieio(); - udelay(2); + udelay(20); sw->select &= ~LSTRB; eieio(); - udelay(1); + udelay(10); out_8(&sw->select, RELAX); } @@ -226,7 +231,7 @@ static int swim3_readbit(struct floppy_state *fs, int bit) int stat; swim3_select(fs, bit); - udelay(1); + udelay(10); stat = in_8(&sw->status); out_8(&sw->select, RELAX); return (stat & DATA) == 0; @@ -234,13 +239,19 @@ static int swim3_readbit(struct floppy_state *fs, int bit) static void do_fd_request(void) { - start_request(&floppy_states[0]); + int i; + for(i=0;istate == idle && fs->wanted) { @@ -261,11 +272,6 @@ static void start_request(struct floppy_state *fs) CURRENT->rq_status, CURRENT->errors, CURRENT->current_nr_sectors); #endif - drive = MINOR(CURRENT->rq_dev); - if (drive != 0) { - end_request(0); - continue; - } if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) { end_request(0); continue; @@ -438,7 +444,7 @@ static void act(struct floppy_state *fs) case settling: /* wait for SEEK_COMPLETE to become true */ swim3_select(fs, SEEK_COMPLETE); - udelay(1); + udelay(10); out_8(&sw->intr_enable, ERROR | DATA_CHANGED); in_8(&sw->intr); /* clear DATA_CHANGED */ if (in_8(&sw->status) & DATA) { @@ -560,7 +566,7 @@ static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs) err = in_8(&sw->error); intr = in_8(&sw->intr); #if 0 - printk(KERN_DEBUG "swim3 intr state=%d intr=%x err=%x\n", fs->state, intr, err); + printk("swim3 intr state=%d intr=%x err=%x\n", fs->state, intr, err); #endif if ((intr & ERROR) && fs->state != do_transfer) printk(KERN_ERR "swim3_interrupt, state=%d, cmd=%x, intr=%x, err=%x\n", @@ -685,9 +691,11 @@ static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs) } } +/* static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { } +*/ static int grab_drive(struct floppy_state *fs, enum swim_state state, int interruptible) @@ -755,12 +763,20 @@ static int floppy_ioctl(struct inode *inode, struct file *filp, { struct floppy_state *fs; int err; + int devnum = MINOR(inode->i_rdev); + if (devnum >= floppy_count) + return -ENODEV; + if (((cmd & 0x40) && !(filp && (filp->f_mode & IOCTL_MODE_BIT))) || ((cmd & 0x80) && !suser())) return -EPERM; - fs = &floppy_states[0]; + fs = &floppy_states[devnum]; + + if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD)) + return -ENXIO; + switch (cmd) { case FDEJECT: if (fs->ref_count != 1) @@ -780,19 +796,21 @@ static int floppy_open(struct inode *inode, struct file *filp) struct floppy_state *fs; volatile struct swim3 *sw; int n, err; + int devnum = MINOR(inode->i_rdev); - if (MINOR(inode->i_rdev) != 0) + if (devnum >= floppy_count) return -ENODEV; - fs = &floppy_states[0]; + + fs = &floppy_states[devnum]; sw = fs->swim3; err = 0; if (fs->ref_count == 0) { - if (fs->in_media_bay && !check_media_bay(MB_FD)) + if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD)) return -ENXIO; out_8(&sw->mode, 0x95); out_8(&sw->control_bic, 0xff); out_8(&sw->reg5, 0x28); - udelay(1); + udelay(10); out_8(&sw->intr_enable, 0); out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE); swim3_action(fs, MOTOR_ON); @@ -856,9 +874,11 @@ static int floppy_release(struct inode *inode, struct file *filp) { struct floppy_state *fs; volatile struct swim3 *sw; + int devnum = MINOR(inode->i_rdev); + + if (devnum >= floppy_count) + return -ENODEV; - if (MINOR(inode->i_rdev) != 0) - return -ENXIO; /* * If filp is NULL, we're being called from blkdev_release * or after a failed mount attempt. In the former case the @@ -868,7 +888,7 @@ static int floppy_release(struct inode *inode, struct file *filp) if (filp && (filp->f_mode & (2 | OPEN_WRITE_BIT))) block_fsync (filp, filp->f_dentry); - fs = &floppy_states[0]; + fs = &floppy_states[devnum]; sw = fs->swim3; if (fs->ref_count > 0 && --fs->ref_count == 0) { swim3_action(fs, MOTOR_OFF); @@ -880,10 +900,12 @@ static int floppy_release(struct inode *inode, struct file *filp) static int floppy_check_change(kdev_t dev) { struct floppy_state *fs; + int devnum = MINOR(dev); - if (MAJOR(dev) != MAJOR_NR || MINOR(dev) != 0) + if (MAJOR(dev) != MAJOR_NR || (devnum >= floppy_count)) return 0; - fs = &floppy_states[0]; + + fs = &floppy_states[devnum]; return fs->ejected; } @@ -892,10 +914,16 @@ static int floppy_revalidate(kdev_t dev) struct floppy_state *fs; volatile struct swim3 *sw; int ret, n; + int devnum = MINOR(dev); - if (MAJOR(dev) != MAJOR_NR || MINOR(dev) != 0) + if (MAJOR(dev) != MAJOR_NR || (devnum >= floppy_count)) return 0; - fs = &floppy_states[0]; + + fs = &floppy_states[devnum]; + + if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD)) + return -ENXIO; + sw = fs->swim3; grab_drive(fs, revalidating, 0); out_8(&sw->intr_enable, 0); @@ -929,10 +957,12 @@ static ssize_t floppy_read(struct file *filp, char *buf, { struct inode *inode = filp->f_dentry->d_inode; struct floppy_state *fs; + int devnum = MINOR(inode->i_rdev); - if (MINOR(inode->i_rdev) != 0) + if (devnum >= floppy_count) return -ENODEV; - fs = &floppy_states[0]; + + fs = &floppy_states[devnum]; if (fs->ejected) return -ENXIO; return block_read(filp, buf, count, ppos); @@ -943,10 +973,12 @@ static ssize_t floppy_write(struct file * filp, const char * buf, { struct inode * inode = filp->f_dentry->d_inode; struct floppy_state *fs; + int devnum = MINOR(inode->i_rdev); - if (MINOR(inode->i_rdev) != 0) + if (devnum >= floppy_count) return -ENODEV; - fs = &floppy_states[0]; + + fs = &floppy_states[devnum]; if (fs->ejected) return -ENXIO; return block_write(filp, buf, count, ppos); @@ -975,50 +1007,72 @@ static struct file_operations floppy_fops = { int swim3_init(void) { - struct device_node *swims; - struct floppy_state *fs = &floppy_states[0]; - int is_3400 = 0; - - if (find_devices("media-bay") != NULL) { - /* assume this is a PB3400 */ - swims = find_devices("floppy"); - is_3400 = 1; - } else { - swims = find_devices("swim3"); + struct device_node *swim; + + swim = find_devices("floppy"); + while (swim && (floppy_count < MAX_FLOPPIES)) + { + swim3_add_device(swim); + swim = swim->next; } - if (swims == NULL) - return 0; + swim = find_devices("swim3"); + while (swim && (floppy_count < MAX_FLOPPIES)) + { + swim3_add_device(swim); + swim = swim->next; + } - if (swims->next != NULL) - printk(KERN_ERR "Warning: only using first SWIM3 floppy controller\n"); - if (swims->n_addrs != 2 || swims->n_intrs != 2) { - printk(KERN_ERR "swim3: expecting 2 addrs and 2 intrs! (%d, %d)\n", - swims->n_addrs, swims->n_intrs); + if (floppy_count > 0) + { + if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) { + printk(KERN_ERR "Unable to get major %d for floppy\n", + MAJOR_NR); + return -EBUSY; + } + blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; + blksize_size[MAJOR_NR] = floppy_blocksizes; + blk_size[MAJOR_NR] = floppy_sizes; + } + + return 0; +} + +static int swim3_add_device(struct device_node *swim) +{ + struct device_node *mediabay; + struct floppy_state *fs = &floppy_states[floppy_count]; + + if (swim->n_addrs < 2) + { + printk(KERN_INFO "swim3: expecting 2 addrs (n_addrs:%d, n_intrs:%d)\n", + swim->n_addrs, swim->n_intrs); return -EINVAL; } - if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) { - printk(KERN_ERR "Unable to get major %d for floppy\n", - MAJOR_NR); - return -EBUSY; + if (swim->n_intrs < 2) + { + printk(KERN_INFO "swim3: expecting 2 intrs (n_addrs:%d, n_intrs:%d)\n", + swim->n_addrs, swim->n_intrs); + return -EINVAL; } - blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; - blksize_size[MAJOR_NR] = floppy_blocksizes; - blk_size[MAJOR_NR] = floppy_sizes; + mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? swim->parent : NULL; + if (mediabay == NULL) + feature_set(swim, FEATURE_SWIM3_enable); + memset(fs, 0, sizeof(*fs)); fs->state = idle; - fs->swim3 = (volatile struct swim3 *) swims->addrs[0].address; - fs->dma = (struct dbdma_regs *) swims->addrs[1].address; - fs->swim3_intr = swims->intrs[0].line; - fs->dma_intr = swims->intrs[1].line; + fs->swim3 = (volatile struct swim3 *) ioremap(swim->addrs[0].address, 0x200); + fs->dma = (struct dbdma_regs *) ioremap(swim->addrs[1].address, 0x200); + fs->swim3_intr = swim->intrs[0].line; + fs->dma_intr = swim->intrs[1].line; fs->cur_cyl = -1; fs->cur_sector = -1; fs->secpercyl = 36; fs->secpertrack = 18; fs->total_secs = 2880; - fs->in_media_bay = is_3400; + fs->media_bay = mediabay; fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space); memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd)); @@ -1026,19 +1080,26 @@ int swim3_init(void) if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { printk(KERN_ERR "Couldn't get irq %d for SWIM3\n", fs->swim3_intr); + feature_clear(swim, FEATURE_SWIM3_enable); return -EBUSY; } +/* if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", fs->dma_intr); + feature_clear(swim, FEATURE_SWIM3_enable); return -EBUSY; } +*/ init_timer(&fs->timeout); do_floppy = NULL; - printk(KERN_INFO "fd0: SWIM3 floppy controller\n"); + printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, + mediabay ? "in media bay" : ""); + floppy_count++; + return 0; } diff --git a/drivers/char/adbmouse.c b/drivers/char/adbmouse.c index 43930ff1b534..39b82c0a432e 100644 --- a/drivers/char/adbmouse.c +++ b/drivers/char/adbmouse.c @@ -3,6 +3,7 @@ * * 27 Oct 1997 Michael Schmitz * logitech fixes by anthony tong + * further hacking by Paul Mackerras * * Apple mouse protocol according to: * @@ -33,14 +34,21 @@ #include #include -#include +#include +#ifdef __powerpc__ #include +#endif +#ifdef __mc68000__ +#include +#endif static struct mouse_status mouse; -static int adb_mouse_x_threshold = 2, adb_mouse_y_threshold = 2; -static int adb_mouse_buttons = 0; +static unsigned char adb_mouse_buttons[16]; -extern void (*adb_mouse_interrupt_hook) (char *, int); +extern void (*adb_mouse_interrupt_hook)(unsigned char *, int); +extern int adb_emulate_buttons; +extern int adb_button2_keycode; +extern int adb_button3_keycode; extern int console_loglevel; @@ -48,11 +56,11 @@ extern int console_loglevel; * XXX: need to figure out what ADB mouse packets mean ... * This is the stuff stolen from the Atari driver ... */ -static void adb_mouse_interrupt(char *buf, int nb) +static void adb_mouse_interrupt(unsigned char *buf, int nb) { - static int buttons = 7; + int buttons, id; - /* +/* Handler 1 -- 100cpi original Apple mouse protocol. Handler 2 -- 200cpi original Apple mouse protocol. @@ -60,76 +68,62 @@ static void adb_mouse_interrupt(char *buf, int nb) contain the following values: BITS COMMENTS - data[0] = 0000 0000 ADB packet identifer. - data[1] = ???? ???? (?) - data[2] = ???? ??00 Bits 0-1 should be zero for a mouse device. - data[3] = bxxx xxxx First button and x-axis motion. - data[4] = byyy yyyy Second button and y-axis motion. - - NOTE: data[0] is confirmed by the parent function and need not be - checked here. - */ + data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd. + data[1] = bxxx xxxx First button and x-axis motion. + data[2] = byyy yyyy Second button and y-axis motion. - /* Handler 4 -- Apple Extended mouse protocol. For Apple's 3-button mouse protocol the data array will contain the following values: BITS COMMENTS - data[0] = 0000 0000 ADB packet identifer. - data[1] = 0100 0000 Extended protocol register. - Bits 6-7 are the device id, which should be 1. - Bits 4-5 are resolution which is in "units/inch". - The Logitech MouseMan returns these bits clear but it has - 200/300cpi resolution. - Bits 0-3 are unique vendor id. - data[2] = 0011 1100 Bits 0-1 should be zero for a mouse device. - Bits 2-3 should be 8 + 4. - Bits 4-7 should be 3 for a mouse device. - data[3] = bxxx xxxx Left button and x-axis motion. - data[4] = byyy yyyy Second button and y-axis motion. - data[5] = byyy bxxx Third button and fourth button. - Y is additiona. high bits of y-axis motion. + data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd. + data[1] = bxxx xxxx Left button and x-axis motion. + data[2] = byyy yyyy Second button and y-axis motion. + data[3] = byyy bxxx Third button and fourth button. + Y is additional high bits of y-axis motion. X is additional high bits of x-axis motion. - NOTE: data[0] and data[2] are confirmed by the parent function and - need not be checked here. - */ + This procedure also gets called from the keyboard code if we + are emulating mouse buttons with keys. In this case data[0] == 0 + (data[0] cannot be 0 for a real ADB packet). - /* - * 'buttons' here means 'button down' states! - * Button 1 (left) : bit 2, busmouse button 3 - * Button 2 (right) : bit 0, busmouse button 1 - * Button 3 (middle): bit 1, busmouse button 2 - */ + 'buttons' here means 'button down' states! + Button 1 (left) : bit 2, busmouse button 3 + Button 2 (middle): bit 1, busmouse button 2 + Button 3 (right) : bit 0, busmouse button 1 +*/ /* x/y and buttons swapped */ - if (nb > 0) { /* real packet : use buttons? */ - if (console_loglevel >= 8) - printk("adb_mouse: real data; "); - /* button 1 (left, bit 2) : always significant ! */ - buttons = (buttons&3) | (buf[1] & 0x80 ? 4 : 0); /* 1+2 unchanged */ - /* button 2 (middle) */ - buttons = (buttons&5) | (buf[2] & 0x80 ? 2 : 0); /* 2+3 unchanged */ - /* button 3 (right) present? - * on a logitech mouseman, the right and mid buttons sometimes behave - * strangely until they both have been pressed after booting. */ - /* data valid only if extended mouse format ! (buf[3] = 0 else) */ - if ( nb == 6 ) - buttons = (buttons&6) | (buf[3] & 0x80 ? 1 : 0); /* 1+3 unchanged */ - } else { /* fake packet : use 2+3 */ - if (console_loglevel >= 8) - printk("adb_mouse: fake data; "); - /* we only see state changes here, but the fake driver takes care - * to preserve state... button 1 state must stay unchanged! */ - buttons = (buttons&4) | ((buf[2] & 0x80 ? 1 : 0) | - (buf[3] & 0x80 ? 2 : 0)); - } - - add_mouse_randomness(((~buttons & 7) << 16) + ((buf[2]&0x7f) << 8) + (buf[1]&0x7f)); - mouse.buttons = buttons & 7; + if (console_loglevel >= 8) + printk("KERN_DEBUG adb_mouse: %s data; ", buf[0]? "real": "fake"); + + id = (buf[0] >> 4) & 0xf; + buttons = adb_mouse_buttons[id]; + + /* button 1 (left, bit 2) */ + buttons = (buttons&3) | (buf[1] & 0x80 ? 4 : 0); /* 1+2 unchanged */ + + /* button 2 (middle) */ + buttons = (buttons&5) | (buf[2] & 0x80 ? 2 : 0); /* 2+3 unchanged */ + + /* button 3 (right) present? + * on a logitech mouseman, the right and mid buttons sometimes behave + * strangely until they both have been pressed after booting. */ + /* data valid only if extended mouse format ! */ + if (nb == 4) + buttons = (buttons&6) | (buf[3] & 0x80 ? 1 : 0); /* 1+3 unchanged */ + + add_mouse_randomness(((~buttons&7) << 16) + ((buf[2]&0x7f) << 8) + (buf[1]&0x7f)); + + adb_mouse_buttons[id] = buttons; + /* a button is down if it is down on any mouse */ + for (id = 0; id < 16; ++id) + buttons &= adb_mouse_buttons[id]; + + mouse.buttons = buttons; mouse.dx += ((buf[2]&0x7f) < 64 ? (buf[2]&0x7f) : (buf[2]&0x7f)-128 ); mouse.dy -= ((buf[1]&0x7f) < 64 ? (buf[1]&0x7f) : (buf[1]&0x7f)-128 ); @@ -141,7 +135,6 @@ static void adb_mouse_interrupt(char *buf, int nb) wake_up_interruptible(&mouse.wait); if (mouse.fasyncptr) kill_fasync(mouse.fasyncptr, SIGIO); - } static int fasync_mouse(int fd, struct file *filp, int on) @@ -167,13 +160,16 @@ static int release_mouse(struct inode *inode, struct file *file) static int open_mouse(struct inode *inode, struct file *file) { + int id; + if (mouse.active++) return 0; mouse.ready = 0; mouse.dx = mouse.dy = 0; - adb_mouse_buttons = 0; + for (id = 0; id < 16; ++id) + adb_mouse_buttons[id] = 7; /* all buttons up */ MOD_INC_USE_COUNT; adb_mouse_interrupt_hook = adb_mouse_interrupt; return 0; @@ -198,24 +194,24 @@ static ssize_t read_mouse(struct file *file, char *buffer, size_t count, dy = mouse.dy; buttons = mouse.buttons; if (dx > 127) - dx = 127; + dx = 127; else if (dx < -128) - dx = -128; + dx = -128; if (dy > 127) - dy = 127; + dy = 127; else if (dy < -128) - dy = -128; + dy = -128; mouse.dx -= dx; mouse.dy -= dy; if (mouse.dx == 0 && mouse.dy == 0) - mouse.ready = 0; + mouse.ready = 0; if (put_user(buttons | 0x80, buffer++) || put_user((char) dx, buffer++) || put_user((char) dy, buffer++)) - return -EFAULT; - if (count > 3) - if (clear_user(buffer, count - 3)) return -EFAULT; + if (count > 3) + if (clear_user(buffer, count - 3)) + return -EFAULT; return count; } @@ -254,40 +250,35 @@ __initfunc(int adb_mouse_init(void)) mouse.ready = 0; mouse.wait = NULL; +#ifdef __powerpc__ if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) return -ENODEV; - printk(KERN_INFO "Macintosh ADB mouse installed.\n"); +#endif +#ifdef __mc68000__ + if (!MACH_IS_MAC) + return -ENODEV; +#endif + printk(KERN_INFO "Macintosh ADB mouse driver installed.\n"); misc_register(&adb_mouse); return 0; } -#define MIN_THRESHOLD 1 -#define MAX_THRESHOLD 20 /* more seems not reasonable... */ - +/* + * XXX this function is misnamed. + * It is called if the kernel is booted with the adb_buttons=xxx + * option, which is about using ADB keyboard buttons to emulate + * mouse buttons. -- paulus + */ __initfunc(void adb_mouse_setup(char *str, int *ints)) { - if (ints[0] < 1) { - printk( "adb_mouse_setup: no arguments!\n" ); - return; - } - else if (ints[0] > 2) { - printk( "adb_mouse_setup: too many arguments\n" ); - } - - if (ints[1] < MIN_THRESHOLD || ints[1] > MAX_THRESHOLD) - printk( "adb_mouse_setup: bad threshold value (ignored)\n" ); - else { - adb_mouse_x_threshold = ints[1]; - adb_mouse_y_threshold = ints[1]; - if (ints[0] > 1) { - if (ints[2] < MIN_THRESHOLD || ints[2] > MAX_THRESHOLD) - printk("adb_mouse_setup: bad threshold value (ignored)\n" ); - else - adb_mouse_y_threshold = ints[2]; + if (ints[0] >= 1) { + adb_emulate_buttons = ints[1] > 0; + if (ints[1] > 1) + adb_button2_keycode = ints[1]; + if (ints[0] >= 2) + adb_button3_keycode = ints[2]; } - } - } #ifdef MODULE diff --git a/drivers/char/lp_m68k.c b/drivers/char/lp_m68k.c index dc0300751dcb..2660c2ca26de 100644 --- a/drivers/char/lp_m68k.c +++ b/drivers/char/lp_m68k.c @@ -477,7 +477,7 @@ EXPORT_SYMBOL(lp_interrupt); EXPORT_SYMBOL(register_parallel); EXPORT_SYMBOL(unregister_parallel); -__initfunc(int lp_init(void)) +__initfunc(int lp_m68k_init(void)) { extern char m68k_debug_device[]; @@ -517,12 +517,12 @@ __initfunc(void lp_setup(char *str, int *ints)) #ifdef MODULE int init_module(void) { -return lp_init(); + return lp_m68k_init(); } void cleanup_module(void) { -unregister_chrdev(LP_MAJOR, "lp"); + unregister_chrdev(LP_MAJOR, "lp"); } #endif diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 67340ed9ae65..d603f22f8abf 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -57,6 +57,11 @@ extern struct tty_driver console_driver; struct vt_struct *vt_cons[MAX_NR_CONSOLES]; +/* Keyboard type: Default is KB_101, but can be set by machine + * specific code. + */ +unsigned char keyboard_type = KB_101; + #ifndef __alpha__ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on); #endif @@ -462,7 +467,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, /* * this is naive. */ - ucval = KB_101; + ucval = keyboard_type; goto setchar; #ifndef __alpha__ diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index 6ab7eba3a98a..74086d99ba03 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -16,14 +16,15 @@ L_TARGET := macintosh.a M_OBJS := ifndef CONFIG_MBX -L_OBJS := via-cuda.o adb.o nvram.o macio-adb.o via-pmu.o mediabay.o +L_OBJS := via-cuda.o nvram.o macio-adb.o via-pmu.o mediabay.o +LX_OBJS := adb.o endif ifeq ($(CONFIG_MAC_SERIAL),y) - LX_OBJS += macserial.o + L_OBJS += macserial.o else ifeq ($(CONFIG_MAC_SERIAL),m) - MX_OBJS += macserial.o + M_OBJS += macserial.o endif endif diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 4c9a67cc0f1d..4bcd1715bd16 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -19,10 +20,13 @@ #include #include +EXPORT_SYMBOL(adb_hardware); + enum adb_hw adb_hardware = ADB_NONE; int (*adb_send_request)(struct adb_request *req, int sync); -int (*adb_autopoll)(int on); -static void adb_scan_bus(void); +int (*adb_autopoll)(int devs); +int (*adb_reset_bus)(void); +static int adb_scan_bus(void); static struct adb_handler { void (*handler)(unsigned char *, int, struct pt_regs *, int); @@ -50,13 +54,13 @@ static void printADBreply(struct adb_request *req) } #endif -static void adb_scan_bus(void) +static int adb_scan_bus(void) { int i, highFree=0, noMovement; + int devmask = 0; struct adb_request req; - /* reset ADB bus */ - /*adb_request(&req, NULL, ADBREQ_SYNC, 1, 0);*/ + adb_reset_bus(); /* reset ADB bus */ /* assumes adb_handler[] is all zeroes at this point */ for (i = 1; i < 16; i++) { @@ -134,24 +138,27 @@ static void adb_scan_bus(void) adb_handler[i].handler_id = req.reply[2]; printk(" [%d]: %d %x", i, adb_handler[i].original_address, adb_handler[i].handler_id); + devmask |= 1 << i; } printk("\n"); + return devmask; } void adb_init(void) { adb_send_request = (void *) adb_nodev; adb_autopoll = (void *) adb_nodev; + adb_reset_bus = adb_nodev; if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) - return; + return; via_cuda_init(); via_pmu_init(); macio_adb_init(); if (adb_hardware == ADB_NONE) printk(KERN_WARNING "Warning: no ADB interface detected\n"); else { - adb_scan_bus(); - adb_autopoll(1); + int devs = adb_scan_bus(); + adb_autopoll(devs); } } @@ -187,8 +194,7 @@ adb_register(int default_id, int handler_id, struct adb_ids *ids, ids->nids = 0; for (i = 1; i < 16; i++) { - if ((adb_handler[i].original_address == default_id) || - (adb_handler[i].handler_id == handler_id)) { + if (adb_handler[i].original_address == default_id) { if (adb_handler[i].handler != 0) { printk(KERN_ERR "Two handlers for ADB device %d\n", diff --git a/drivers/macintosh/mac_keyb.c b/drivers/macintosh/mac_keyb.c index 5c49af36fb5b..c2ff83b8345f 100644 --- a/drivers/macintosh/mac_keyb.c +++ b/drivers/macintosh/mac_keyb.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -170,16 +172,22 @@ static int last_keycode; static void keyboard_input(unsigned char *, int, struct pt_regs *, int); static void input_keycode(int, int); static void leds_done(struct adb_request *); +static void mac_put_queue(int); +#ifdef CONFIG_ADBMOUSE /* XXX: Hook for mouse driver */ -void (*adb_mouse_interrupt_hook) (char *, int); -static int adb_emulate_buttons = 0; +void (*adb_mouse_interrupt_hook)(unsigned char *, int); +int adb_emulate_buttons = 0; +int adb_button2_keycode = 0x7d; /* right control key */ +int adb_button3_keycode = 0x7c; /* right option key */ +#endif + extern int console_loglevel; extern struct kbd_struct kbd_table[]; +extern struct wait_queue * keypress_wait; extern void handle_scancode(unsigned char); -extern void put_queue(int); static struct adb_ids keyboard_ids; static struct adb_ids mouse_ids; @@ -264,6 +272,7 @@ input_keycode(int keycode, int repeat) if (!repeat) del_timer(&repeat_timer); +#ifdef CONFIG_ADBMOUSE /* * XXX: Add mouse button 2+3 fake codes here if mouse open. * Keep track of 'button' states here as we only send @@ -273,52 +282,27 @@ input_keycode(int keycode, int repeat) * Might also want to know how many buttons need to be emulated. * -> hide this as function in arch/m68k/mac ? */ - if ( (adb_emulate_buttons) && - (adb_mouse_interrupt_hook || console_loglevel == 10) ) { - unsigned char button, button2, button3, fake_event; - static unsigned char button2state=0, button3state=0; /* up */ + if (adb_emulate_buttons + && (keycode == adb_button2_keycode + || keycode == adb_button3_keycode) + && (adb_mouse_interrupt_hook || console_loglevel == 10)) { + int button; /* faked ADB packet */ - static char data[4] = { 0, 0x80, 0x80, 0x80 }; - - button = 0; - fake_event = 0; - switch (keycode) { /* which 'button' ? */ - case 0x7c: /* R-option */ - button3 = (!up_flag); /* new state */ - if (button3 != button3state) /* change ? */ - button = 3; - button3state = button3; /* save state */ - fake_event = 3; - break; - case 0x7d: /* R-control */ - button2 = (!up_flag); /* new state */ - if (button2 != button2state) /* change ? */ - button = 2; - button2state = button2; /* save state */ - fake_event = 2; - break; - } - if (fake_event && console_loglevel >= 8) - printk("fake event: button2 %d button3 %d button %d\n", - button2state, button3state, button); - if (button) { /* there's been a button state change */ - /* fake a mouse packet : send all bytes, change one! */ - data[button] = (up_flag ? 0x80 : 0); + static unsigned char data[4] = { 0, 0x80, 0x80, 0x80 }; + + button = keycode == adb_button2_keycode? 2: 3; + if (data[button] != up_flag) { + /* send a fake mouse packet */ + data[button] = up_flag; + if (console_loglevel >= 8) + printk("fake mouse event: %x %x %x\n", + data[1], data[2], data[3]); if (adb_mouse_interrupt_hook) - adb_mouse_interrupt_hook(data, -1); - else - printk("mouse_fake: data %x %x %x buttons %x \n", - data[1], data[2], data[3], - ~( (data[1] & 0x80 ? 0 : 4) - | (data[2] & 0x80 ? 0 : 1) - | (data[3] & 0x80 ? 0 : 2) )&7 ); + adb_mouse_interrupt_hook(data, 4); } - /* - * XXX: testing mouse emulation ... don't process fake keys! - */ - if (fake_event) - return; + return; } +#endif /* CONFIG_ADBMOUSE */ if (kbd->kbdmode != VC_RAW) { if (!up_flag && !dont_repeat[keycode]) { @@ -361,6 +345,20 @@ kbd_repeat(unsigned long xxx) restore_flags(flags); } +static void mac_put_queue(int ch) +{ + extern struct tty_driver console_driver; + struct tty_struct *tty; + + tty = console_driver.table? console_driver.table[fg_console]: NULL; + wake_up(&keypress_wait); + if (tty) { + tty_insert_flip_char(tty, ch, 0); + con_schedule_flip(tty); + } +} + +#ifdef CONFIG_ADBMOUSE static void mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) { @@ -399,62 +397,34 @@ mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) */ /* + Handler 1 -- 100cpi original Apple mouse protocol. + Handler 2 -- 200cpi original Apple mouse protocol. + + For Apple's standard one-button mouse protocol the data array will + contain the following values: + + BITS COMMENTS + data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd. + data[1] = bxxx xxxx First button and x-axis motion. + data[2] = byyy yyyy Second button and y-axis motion. + Handler 4 -- Apple Extended mouse protocol. For Apple's 3-button mouse protocol the data array will contain the following values: BITS COMMENTS - data[0] = 0000 0000 ADB packet identifer. - data[1] = 0100 0000 Extended protocol register. - Bits 6-7 are the device id, which should be 1. - Bits 4-5 are resolution which is in "units/inch". - The Logitech MouseMan returns these bits clear but it has - 200/300cpi resolution. - Bits 0-3 are unique vendor id. - data[2] = 0011 1100 Bits 0-1 should be zero for a mouse device. - Bits 2-3 should be 8 + 4. - Bits 4-7 should be 3 for a mouse device. - data[3] = bxxx xxxx Left button and x-axis motion. - data[4] = byyy yyyy Second button and y-axis motion. - data[5] = byyy bxxx Third button and fourth button. Y is additional + data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd. + data[1] = bxxx xxxx Left button and x-axis motion. + data[2] = byyy yyyy Second button and y-axis motion. + data[3] = byyy bxxx Third button and fourth button. Y is additional high bits of y-axis motion. XY is additional high bits of x-axis motion. - - NOTE: data[0] and data[2] are confirmed by the parent function and - need not be checked here. - */ - - /* - Handler 1 -- 100cpi original Apple mouse protocol. - Handler 2 -- 200cpi original Apple mouse protocol. - - For Apple's standard one-button mouse protocol the data array will - contain the following values: - - BITS COMMENTS - data[0] = 0000 0000 ADB packet identifer. - data[1] = ???? ???? (?) - data[2] = ???? ??00 Bits 0-1 should be zero for a mouse device. - data[3] = bxxx xxxx First button and x-axis motion. - data[4] = byyy yyyy Second button and y-axis motion. - - NOTE: data[0] is confirmed by the parent function and need not be - checked here. */ struct kbd_struct *kbd; if (adb_mouse_interrupt_hook) adb_mouse_interrupt_hook(data, nb); - else - if (console_loglevel == 10) - printk("mouse_input: data %x %x %x buttons %x dx %d dy %d \n", - data[1], data[2], data[3], - ~((data[1] & 0x80 ? 0 : 4) - | (data[2] & 0x80 ? 0 : 1) - | (data[3] & 0x80 ? 0 : 2))&7, - ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ), - ((data[1]&0x7f) < 64 ? -(data[1]&0x7f) : 128-(data[1]&0x7f) ) ); kbd = kbd_table + fg_console; @@ -464,9 +434,9 @@ mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) unsigned char uchButtonSecond; /* Send first button, second button and movement. */ - put_queue( 0x7e ); - put_queue( data[1] ); - put_queue( data[2] ); + mac_put_queue(0x7e); + mac_put_queue(data[1]); + mac_put_queue(data[2]); /* [ACA: Are there any two-button ADB mice that use handler 1 or 2?] */ @@ -475,12 +445,12 @@ mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) /* Send second button. */ if (uchButtonSecond != uch_ButtonStateSecond) { - put_queue( 0x3f | uchButtonSecond ); + mac_put_queue(0x3f | uchButtonSecond); uch_ButtonStateSecond = uchButtonSecond; } /* Macintosh 3-button mouse (handler 4). */ - if ((nb == 4) && autopoll /*?*/) { + if (nb == 4) { static unsigned char uch_ButtonStateThird = 0x80; unsigned char uchButtonThird; @@ -489,12 +459,13 @@ mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) /* Send third button. */ if (uchButtonThird != uch_ButtonStateThird) { - put_queue( 0x40 | uchButtonThird ); + mac_put_queue(0x40 | uchButtonThird); uch_ButtonStateThird = uchButtonThird; } } } } +#endif /* CONFIG_ADBMOUSE */ /* Map led flags as defined in kbd_kern.h to bits for Apple keyboard. */ static unsigned char mac_ledmap[8] = { @@ -571,11 +542,14 @@ __initfunc(void mackbd_init_hw(void)) memcpy(key_maps[8], macalt_map, sizeof(plain_map)); memcpy(key_maps[12], macctrl_alt_map, sizeof(plain_map)); +#ifdef CONFIG_ADBMOUSE /* initialize mouse interrupt hook */ adb_mouse_interrupt_hook = NULL; - adb_register(ADB_KEYBOARD, 5, &keyboard_ids, keyboard_input); adb_register(ADB_MOUSE, 1, &mouse_ids, mouse_input); +#endif /* CONFIG_ADBMOUSE */ + + adb_register(ADB_KEYBOARD, 5, &keyboard_ids, keyboard_input); for(i = 0; i < keyboard_ids.nids; i++) { /* turn off all leds */ @@ -634,9 +608,3 @@ __initfunc(void mackbd_init_hw(void)) } } } - -void adb_setup_mouse( char *s, int *ints ) -{ - if (ints[0] >= 1) - adb_emulate_buttons = ints[1]; -} diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c index 0af447c083d8..b3e7b0ec2b6b 100644 --- a/drivers/macintosh/macio-adb.c +++ b/drivers/macintosh/macio-adb.c @@ -61,8 +61,9 @@ static unsigned char adb_rbuf[16]; static void macio_adb_interrupt(int irq, void *arg, struct pt_regs *regs); static int macio_adb_send_request(struct adb_request *req, int sync); -static int macio_adb_autopoll(int on); +static int macio_adb_autopoll(int devs); static void macio_adb_poll(void); +static int macio_reset_bus(void); static void completed(void); __openfirmware @@ -108,14 +109,30 @@ void macio_adb_init(void) adb_hardware = ADB_MACIO; adb_send_request = macio_adb_send_request; adb_autopoll = macio_adb_autopoll; + adb_reset_bus = macio_reset_bus; } -static int macio_adb_autopoll(int on) +static int macio_adb_autopoll(int devs) { - out_8(&adb->autopoll.r, on? APE: 0); + out_8(&adb->active_hi.r, devs >> 8); + out_8(&adb->active_lo.r, devs); + out_8(&adb->autopoll.r, devs? APE: 0); return 0; } +static int macio_reset_bus(void) +{ + int timeout = 1000000; + + out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | ADB_RST); + while ((in_8(&adb->ctrl.r) & ADB_RST) != 0) { + if (--timeout == 0) { + out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) & ~ADB_RST); + return -1; + } + } + return 0; +} /* Send an ADB command */ static int macio_adb_send_request(struct adb_request *req, int sync) diff --git a/drivers/macintosh/macserial.c b/drivers/macintosh/macserial.c index 0178b6ebb765..bfb75e3b75d8 100644 --- a/drivers/macintosh/macserial.c +++ b/drivers/macintosh/macserial.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef CONFIG_KGDB #include #endif @@ -85,7 +86,8 @@ static DECLARE_TASK_QUEUE(tq_serial); static struct tty_driver serial_driver, callout_driver; static int serial_refcount; -/* serial subtype definitions */ +/* serial supmac_irq_hw *) 0xf3000010, +btype definitions */ #define SERIAL_TYPE_NORMAL 1 #define SERIAL_TYPE_CALLOUT 2 @@ -165,25 +167,35 @@ static inline unsigned char read_zsreg(struct mac_zschannel *channel, unsigned char reg) { unsigned char retval; + unsigned long flags; + /* + * We have to make this atomic. + */ + spin_lock_irqsave(&channel->lock, flags); if (reg != 0) { *channel->control = reg; RECOVERY_DELAY; } retval = *channel->control; RECOVERY_DELAY; + spin_unlock_irqrestore(&channel->lock, flags); return retval; } static inline void write_zsreg(struct mac_zschannel *channel, unsigned char reg, unsigned char value) { + unsigned long flags; + + spin_lock_irqsave(&channel->lock, flags); if (reg != 0) { *channel->control = reg; RECOVERY_DELAY; } *channel->control = value; RECOVERY_DELAY; + spin_unlock_irqrestore(&channel->lock, flags); return; } @@ -434,6 +446,10 @@ static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) for (;;) { zs_intreg = read_zsreg(info->zs_chan_a, 3) >> shift; +#ifdef SERIAL_DEBUG_INTR +// printk("rs_interrupt: irq %d, zs_intreg 0x%x\n", irq, (int)zs_intreg); +#endif + if ((zs_intreg & CHAN_IRQMASK) == 0) break; @@ -1261,6 +1277,15 @@ static void rs_close(struct tty_struct *tty, struct file * filp) tty->closing = 0; info->event = 0; info->tty = 0; + + if (info->is_cobalt_modem) { + /* Power down modem */ + feature_set(info->dev_node, FEATURE_Modem_Reset); + mdelay(15); + feature_clear(info->dev_node, FEATURE_Modem_PowerOn); + mdelay(15); + } + if (info->blocked_open) { if (info->close_delay) { current->state = TASK_INTERRUPTIBLE; @@ -1271,6 +1296,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE| ZILOG_CLOSING); wake_up_interruptible(&info->close_wait); + restore_flags(flags); } @@ -1508,9 +1534,25 @@ static int rs_open(struct tty_struct *tty, struct file * filp) /* * Start up serial port */ + + if (info->is_cobalt_modem) { + /* Power up modem */ + feature_set(info->dev_node, FEATURE_Modem_PowerOn); + mdelay(250); + feature_clear(info->dev_node, FEATURE_Modem_Reset); + mdelay(10); + } retval = startup(info); - if (retval) + if (retval) { + if (info->is_cobalt_modem) { + /* Power down modem */ + feature_set(info->dev_node, FEATURE_Modem_Reset); + mdelay(15); + feature_clear(info->dev_node, FEATURE_Modem_PowerOn); + mdelay(15); + } return retval; + } retval = block_til_ready(tty, filp, info); if (retval) { @@ -1518,6 +1560,13 @@ static int rs_open(struct tty_struct *tty, struct file * filp) printk("rs_open returning after block_til_ready with %d\n", retval); #endif + if (info->is_cobalt_modem) { + /* Power down modem */ + feature_set(info->dev_node, FEATURE_Modem_Reset); + mdelay(15); + feature_clear(info->dev_node, FEATURE_Modem_PowerOn); + mdelay(15); + } return retval; } @@ -1568,8 +1617,14 @@ probe_sccs() dev->full_name); continue; } + feature_clear(dev, FEATURE_Serial_reset); + mdelay(5); + feature_set(dev, FEATURE_Serial_enable); + feature_set(dev, FEATURE_Serial_IO_A); + feature_set(dev, FEATURE_Serial_IO_B); + mdelay(5); for (ch = dev->child; ch != 0; ch = ch->sibling) { - if (ch->n_addrs < 1 || ch ->n_intrs < 1) { + if (ch->n_addrs < 1 || (ch ->n_intrs < 1)) { printk("Can't use %s: %d addrs %d intrs\n", ch->full_name, ch->n_addrs, ch->n_intrs); continue; @@ -1578,8 +1633,20 @@ probe_sccs() ioremap(ch->addrs[0].address, 0x1000); zs_channels[n].data = zs_channels[n].control + ch->addrs[0].size / 2; + spin_lock_init(&zs_channels[n].lock); zs_soft[n].zs_channel = &zs_channels[n]; + zs_soft[n].dev_node = ch; zs_soft[n].irq = ch->intrs[0].line; + zs_soft[n].is_cobalt_modem = device_is_compatible(ch, "cobalt"); + if (zs_soft[n].is_cobalt_modem) + { + /* Just in case the modem is up, shut it down */ + feature_set(ch, FEATURE_Modem_Reset); + mdelay(15); + feature_clear(ch, FEATURE_Modem_PowerOn); + mdelay(15); + } + /* XXX this assumes the prom puts chan A before B */ if (n & 1) zs_soft[n].zs_chan_a = &zs_channels[n-1]; @@ -1696,6 +1763,9 @@ int macserial_init(void) for (info = zs_chain, i = 0; info; info = info->zs_next, i++) { + unsigned char* connector; + int lenp; + #ifdef CONFIG_KGDB if (info->kgdb_channel) { continue; @@ -1719,8 +1789,14 @@ int macserial_init(void) info->open_wait = 0; info->close_wait = 0; printk("tty%02d at 0x%08x (irq = %d)", info->line, - info->port, info->irq); - printk(" is a Z8530 ESCC\n"); + info->port, info->irq); + printk(" is a Z8530 ESCC"); + connector = get_property(info->dev_node, "AAPL,connector", &lenp); + if (connector) + printk(", port = %s", connector); + if (info->is_cobalt_modem) + printk(" (cobalt modem)"); + printk("\n"); } restore_flags(flags); diff --git a/drivers/macintosh/macserial.h b/drivers/macintosh/macserial.h index 83e6dc93261d..ec7552f96233 100644 --- a/drivers/macintosh/macserial.h +++ b/drivers/macintosh/macserial.h @@ -84,6 +84,7 @@ struct serial_struct { struct mac_zschannel { volatile unsigned char *control; volatile unsigned char *data; + spinlock_t lock; }; struct mac_serial { @@ -91,11 +92,13 @@ struct mac_serial { struct mac_zschannel *zs_channel; /* Channel registers */ struct mac_zschannel *zs_chan_a; /* A side registers */ unsigned char read_reg_zero; + struct device_node* dev_node; char soft_carrier; /* Use soft carrier on this channel */ char break_abort; /* Is serial console in, so process brk/abrt */ char kgdb_channel; /* Kgdb is running on this channel */ char is_cons; /* Is this our console. */ + char is_cobalt_modem; /* is a gatwick-based cobalt modem */ unsigned char tx_active; /* character is being xmitted */ unsigned char tx_stopped; /* output is suspended */ diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 90490bb512c4..13ce064f4880 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -8,6 +8,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#define __KERNEL_SYSCALLS__ + #include #include #include @@ -16,44 +18,54 @@ #include #include #include +#include +#include #include #include #include -#include +#include #include #include + +#undef MB_USE_INTERRUPTS + struct media_bay_hw { unsigned char b0; unsigned char contents; unsigned char b2; unsigned char b3; - unsigned feature; }; -static volatile struct media_bay_hw *mb_addr; +struct media_bay_info { + volatile struct media_bay_hw* addr; + int content_id; + int previous_id; + int ready; + int last_value; + int value_count; + int reset_timer; + struct device_node* dev_node; +#ifdef CONFIG_BLK_DEV_IDE + unsigned long cd_base; + int cd_index; + int cd_irq; + int cd_timer; +#endif +}; -#define MB_CONTENTS() ((in_8(&mb_addr->contents) >> 4) & 7) -#define SET_FEATURES(set, clr) \ - out_le32(&mb_addr->feature, \ - (in_le32(&mb_addr->feature) & ~(clr)) | (set)); +#define MAX_BAYS 2 -static int media_bay_id = -1; -static int mb_ready; -static int mb_last_value; -static int mb_value_count; +static volatile struct media_bay_info media_bays[MAX_BAYS]; +int media_bay_count = 0; -int media_bay_present; +#define MB_CONTENTS(i) ((in_8(&media_bays[i].addr->contents) >> 4) & 7) #ifdef CONFIG_BLK_DEV_IDE -unsigned long mb_cd_base; -int mb_cd_index = -1; -int mb_cd_irq; - /* check the busy bit in the media-bay ide interface (assumes the media-bay contains an ide device) */ -#define MB_IDE_READY() ((in_8((volatile unsigned char *) \ - (mb_cd_base + 0x70)) & 0x80) == 0) +#define MB_IDE_READY(i) ((in_8((volatile unsigned char *) \ + (media_bays[i].cd_base + 0x70)) & 0x80) == 0) #endif /* @@ -66,16 +78,17 @@ int mb_cd_irq; * Hold the media-bay reset signal true for this many ticks * after a device is inserted before releasing it. */ -#define MB_RESET_COUNT 10 +#define MB_RESET_COUNT 20 /* * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted * (or until the device is ready) before registering the IDE interface. */ -#define MB_IDE_WAIT 500 +#define MB_IDE_WAIT 1000 -static void poll_media_bay(void); -static void set_media_bay(int id); +static void poll_media_bay(int which); +static void set_media_bay(int which, int id); +static int media_bay_task(void *); /* * It seems that the bit for the media-bay interrupt in the IRQ_LEVEL @@ -92,29 +105,62 @@ void media_bay_init(void) { struct device_node *np; - + int n,i; + + for (i=0; in_addrs == 0) - return; - mb_addr = (volatile struct media_bay_hw *) - ioremap(np->addrs[0].address, sizeof(struct media_bay_hw)); + n = 0; + while(np && (nn_addrs == 0) + continue; + media_bays[n].addr = (volatile struct media_bay_hw *) + ioremap(np->addrs[0].address, sizeof(struct media_bay_hw)); -#if 0 - if (np->n_intrs == 0) { - printk(KERN_WARNING "No interrupt for media bay?\n"); - } else { - if (request_irq(np->intrs[0].line, media_bay_intr, 0, - "Media bay", NULL)) - printk(KERN_WARNING "Couldn't get IRQ %d for " - "media bay\n", np->intrs[0].line); - } +#ifdef MB_USE_INTERRUPTS + if (np->n_intrs == 0) + { + printk(KERN_ERR "media bay %d has no irq\n",n); + continue; + } + + if (request_irq(np_intrs[0].line, media_bay_intr, 0, "Media bay", NULL)) + { + printk(KERN_ERR "Couldn't get IRQ %d for media bay %d\n", irq, n); + continue; + } +#endif + media_bay_count++; + + set_media_bay(n, MB_CONTENTS(n)); + if (media_bays[n].content_id != MB_NO) { + feature_clear(media_bays[n].dev_node, FEATURE_Mediabay_reset); + udelay(500); + } + media_bays[n].ready = 1; + media_bays[n].previous_id = media_bays[n].content_id; + media_bays[n].reset_timer = 0; + media_bays[n].dev_node = np; +#ifdef CONFIG_BLK_DEV_IDE + media_bays[n].cd_timer = 0; #endif + n++; + np=np->next; + } + + if (media_bay_count) + { + printk(KERN_INFO "Registered %d media-bay(s)\n", media_bay_count); - media_bay_present = 1; - set_media_bay(MB_CONTENTS()); - if (media_bay_id != MB_NO) { - SET_FEATURES(0, OH_BAY_RESET); - mb_ready = 1; + kernel_thread(media_bay_task, NULL, 0); } } @@ -130,9 +176,61 @@ media_bay_intr(int irq, void *devid, struct pt_regs *regs) #endif int -check_media_bay(int what) +check_media_bay(struct device_node *which_bay, int what) +{ +#ifdef CONFIG_BLK_DEV_IDE + int i; + + for (i=0; icomm, "media-bay"); - for (;;) { - poll_media_bay(); - if (media_bay_id != prev) { - reset_timer = (media_bay_id != MB_NO)? + for (;;) + { + bay = &media_bays[i]; + poll_media_bay(i); + if (bay->content_id != bay->previous_id) { + bay->reset_timer = (bay->content_id != MB_NO) ? MB_RESET_COUNT: 0; - mb_ready = 0; + bay->ready = 0; #ifdef CONFIG_BLK_DEV_IDE - cd_timer = 0; - if (media_bay_id != MB_CD && mb_cd_index >= 0) { - printk(KERN_DEBUG "Unregistering mb ide\n"); - ide_unregister(mb_cd_index); - mb_cd_index = -1; + bay->cd_timer = 0; + if (bay->content_id != MB_CD && bay->cd_index >= 0) { + printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i, bay->cd_index); + ide_unregister(bay->cd_index); + bay->cd_index = -1; } #endif - } else if (reset_timer) { - if (--reset_timer == 0) { - SET_FEATURES(0, OH_BAY_RESET); - mb_ready = 1; + } else if (bay->reset_timer) { + if (--bay->reset_timer == 0) { + feature_clear(bay->dev_node, FEATURE_Mediabay_reset); + bay->ready = 1; #ifdef CONFIG_BLK_DEV_IDE - if (media_bay_id == MB_CD && mb_cd_base != 0) - cd_timer = MB_IDE_WAIT; + bay->cd_timer = 0; + if (bay->content_id == MB_CD && bay->cd_base != 0) + bay->cd_timer = MB_IDE_WAIT; #endif } #ifdef CONFIG_BLK_DEV_IDE - } else if (cd_timer && (--cd_timer == 0 || MB_IDE_READY()) - && mb_cd_index < 0) { - mb_cd_index = ide_register(mb_cd_base, 0, mb_cd_irq); - printk(KERN_DEBUG "media-bay is ide %d\n", mb_cd_index); + } else if (bay->cd_timer && (--bay->cd_timer == 0 || MB_IDE_READY(i)) + && bay->cd_index < 0) { + bay->cd_timer = 0; + printk(KERN_DEBUG "Registering IDE, base:0x%08lx, irq:%d\n", bay->cd_base, bay->cd_irq); + printk("\n"); + bay->cd_index = ide_register(bay->cd_base, 0, bay->cd_irq); + if (bay->cd_index == -1) + printk("\nCD-ROM badly inserted. Remove it and try again !\n"); + else + printk(KERN_DEBUG "media-bay %d is ide %d\n", i, bay->cd_index); #endif } - prev = media_bay_id; + bay->previous_id = bay->content_id; current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); if (signal_pending(current)) return 0; + i = (i+1)%media_bay_count; } } void -poll_media_bay(void) +poll_media_bay(int which) { - int id = MB_CONTENTS(); + int id = MB_CONTENTS(which); - if (id == mb_last_value) { - if (id != media_bay_id - && ++mb_value_count >= MB_STABLE_COUNT) - set_media_bay(id); + if (id == media_bays[which].last_value) { + if (id != media_bays[which].content_id + && ++media_bays[which].value_count >= MB_STABLE_COUNT) + set_media_bay(which, id); } else { - mb_last_value = id; - mb_value_count = 0; + media_bays[which].last_value = id; + media_bays[which].value_count = 0; } } static void -set_media_bay(int id) +set_media_bay(int which, int id) { - u32 clr, set; + volatile struct media_bay_info* bay; - media_bay_id = id; - mb_last_value = id; - clr = OH_FLOPPY_ENABLE | OH_IDECD_POWER; - set = 0; + bay = &media_bays[which]; + + bay->content_id = id; + bay->last_value = id; + switch (id) { case MB_CD: - set = OH_BAY_ENABLE | OH_IDECD_POWER | OH_BAY_IDE_ENABLE; - printk(KERN_INFO "media bay contains a CD-ROM drive\n"); + feature_clear(bay->dev_node, FEATURE_Mediabay_floppy_enable); + feature_set(bay->dev_node, FEATURE_Mediabay_enable); + feature_set(bay->dev_node, FEATURE_CD_power); + feature_set(bay->dev_node, FEATURE_Mediabay_IDE_enable); + printk(KERN_INFO "media bay %d contains a CD-ROM drive\n", which); break; case MB_FD: - set = OH_BAY_ENABLE | OH_BAY_FLOPPY_ENABLE | OH_FLOPPY_ENABLE; - printk(KERN_INFO "media bay contains a floppy disk drive\n"); + feature_clear(bay->dev_node, FEATURE_CD_power); + feature_set(bay->dev_node, FEATURE_Mediabay_enable); + feature_set(bay->dev_node, FEATURE_Mediabay_floppy_enable); + feature_set(bay->dev_node, FEATURE_SWIM3_enable); + printk(KERN_INFO "media bay %d contains a floppy disk drive\n", which); break; case MB_NO: - printk(KERN_INFO "media bay is empty\n"); + feature_clear(bay->dev_node, FEATURE_Mediabay_floppy_enable); + feature_clear(bay->dev_node, FEATURE_CD_power); + printk(KERN_INFO "media bay %d is empty\n", which); break; default: - set = OH_BAY_ENABLE; - printk(KERN_INFO "media bay contains an unknown device (%d)\n", - id); + feature_clear(bay->dev_node, FEATURE_Mediabay_floppy_enable); + feature_clear(bay->dev_node, FEATURE_CD_power); + feature_set(bay->dev_node, FEATURE_Mediabay_enable); + printk(KERN_INFO "media bay %d contains an unknown device (%d)\n", + which, id); break; } - - SET_FEATURES(set, clr); - printk(KERN_DEBUG "feature reg now %x\n", in_le32(&mb_addr->feature)); + + udelay(500); } diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index 986cdd7b5096..b0b7dd7d2ff2 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c @@ -80,7 +80,8 @@ static void cuda_start(void); static void via_interrupt(int irq, void *arg, struct pt_regs *regs); static void cuda_input(unsigned char *buf, int nb, struct pt_regs *regs); static int cuda_adb_send_request(struct adb_request *req, int sync); -static int cuda_adb_autopoll(int on); +static int cuda_adb_autopoll(int devs); +static int cuda_reset_bus(void); __openfirmware @@ -141,6 +142,7 @@ via_cuda_init(void) /* Set function pointers */ adb_send_request = cuda_adb_send_request; adb_autopoll = cuda_adb_autopoll; + adb_reset_bus = cuda_reset_bus; } #define WAIT_FOR(cond, what) \ @@ -216,11 +218,23 @@ cuda_adb_send_request(struct adb_request *req, int sync) /* Enable/disable autopolling */ static int -cuda_adb_autopoll(int on) +cuda_adb_autopoll(int devs) { struct adb_request req; - cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, on); + cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, (devs? 1: 0)); + while (!req.complete) + cuda_poll(); + return 0; +} + +/* Reset adb bus - how do we do this?? */ +static int +cuda_reset_bus(void) +{ + struct adb_request req; + + cuda_request(&req, NULL, 2, ADB_PACKET, 0); /* maybe? */ while (!req.complete) cuda_poll(); return 0; diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 407a930026a7..4dd82fef9366 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -30,6 +30,7 @@ #include #include #include +#include /* Misc minor number allocated for /dev/pmu */ #define PMU_MINOR 154 @@ -99,7 +100,8 @@ static int pmu_queue_request(struct adb_request *req); static void pmu_start(void); static void via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs); static int pmu_adb_send_request(struct adb_request *req, int sync); -static int pmu_adb_autopoll(int on); +static int pmu_adb_autopoll(int devs); +static int pmu_reset_bus(void); static void send_byte(int x); static void recv_byte(void); static void pmu_sr_intr(struct pt_regs *regs); @@ -162,6 +164,8 @@ find_via_pmu() return; if (vias->next != 0) printk(KERN_WARNING "Warning: only using 1st via-pmu\n"); + + feature_set(vias, FEATURE_VIA_enable); #if 0 { int i; @@ -215,6 +219,7 @@ via_pmu_init(void) /* Set function pointers */ adb_send_request = pmu_adb_send_request; adb_autopoll = pmu_adb_autopoll; + adb_reset_bus = pmu_reset_bus; } static int @@ -281,11 +286,12 @@ pmu_adb_send_request(struct adb_request *req, int sync) /* Enable/disable autopolling */ static int -pmu_adb_autopoll(int on) +pmu_adb_autopoll(int devs) { struct adb_request req; - if (on) { + if (devs) { + adb_dev_map = devs; pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86, adb_dev_map >> 8, adb_dev_map); pmu_adb_flags = 2; @@ -298,6 +304,49 @@ pmu_adb_autopoll(int on) return 0; } +/* Reset the ADB bus */ +static int +pmu_reset_bus(void) +{ + struct adb_request req; + long timeout; + int save_autopoll = adb_dev_map; + + /* anyone got a better idea?? */ + pmu_adb_autopoll(0); + + req.nbytes = 5; + req.done = NULL; + req.data[0] = PMU_ADB_CMD; + req.data[1] = 0; + req.data[2] = 3; + req.data[3] = 0; + req.data[4] = 0; + req.reply_len = 0; + req.reply_expected = 1; + if (pmu_queue_request(&req) != 0) + { + printk(KERN_ERR "pmu_reset_bus: pmu_queue_request failed\n"); + return 0; + } + while (!req.complete) + pmu_poll(); + timeout = 100000; + while (!req.complete) { + if (--timeout < 0) { + printk(KERN_ERR "pmu_reset_bus (reset): no response from PMU\n"); + return 0; + } + udelay(10); + pmu_poll(); + } + + if (save_autopoll != 0) + pmu_adb_autopoll(save_autopoll); + + return 1; +} + /* Construct and send a pmu request */ int pmu_request(struct adb_request *req, void (*done)(struct adb_request *), @@ -366,7 +415,10 @@ pmu_send_request(struct adb_request *req) req->nbytes = 5; for (i = 1; i <= 4; ++i) req->data[i] = req->data[i+1]; - req->reply_len = 0; + req->reply_len = 3; + req->reply[0] = CUDA_PACKET; + req->reply[1] = 0; + req->reply[2] = CUDA_SET_TIME; return pmu_queue_request(req); } break; @@ -691,6 +743,44 @@ set_volume(int level) { } +void +pmu_restart(void) +{ + struct adb_request req; + + _disable_interrupts(); + + pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, CB1_INT); + while(!req.complete) + pmu_poll(); + + pmu_request(&req, NULL, 1, PMU_RESET); + while(!req.complete || (pmu_state != idle)) + pmu_poll(); + for (;;) + ; +} + +void +pmu_shutdown(void) +{ + struct adb_request req; + + _disable_interrupts(); + + pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, CB1_INT); + while(!req.complete) + pmu_poll(); + + pmu_request(&req, NULL, 5, PMU_SHUTDOWN, + 'M', 'A', 'T', 'T'); + while(!req.complete || (pmu_state != idle)) + pmu_poll(); + for (;;) + ; +} + + #ifdef CONFIG_PMAC_PBOOK /* @@ -855,12 +945,14 @@ int powerbook_sleep(void) notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); /* reenable ADB autopoll */ - pmu_adb_autopoll(1); + pmu_adb_autopoll(adb_dev_map); /* Turn on the screen backlight, if it was on before */ if (save_backlight) pmu_enable_backlight(1); + /* Wait for the hard disk to spin up */ + return 0; } diff --git a/drivers/misc/parport_arc.c b/drivers/misc/parport_arc.c index b231e9ee0f27..134bec7d7f35 100644 --- a/drivers/misc/parport_arc.c +++ b/drivers/misc/parport_arc.c @@ -14,6 +14,7 @@ * a subset of the standard printer control lines connected. */ +#include #include #include #include diff --git a/drivers/misc/parport_ax.c b/drivers/misc/parport_ax.c index bbd544640b5a..1360dc17f553 100644 --- a/drivers/misc/parport_ax.c +++ b/drivers/misc/parport_ax.c @@ -11,6 +11,7 @@ * Grant Guenther */ +#include #include #include #include diff --git a/drivers/misc/parport_pc.c b/drivers/misc/parport_pc.c index c493246dd5e6..cddb1dffe15c 100644 --- a/drivers/misc/parport_pc.c +++ b/drivers/misc/parport_pc.c @@ -34,6 +34,7 @@ * accomodate this. */ +#include #include #include #include diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 9e9cf4a42a7f..8eb71101dd79 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -33,6 +33,7 @@ static const char *version = "at1700.c:v1.15 4/7/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; +#include #include #include diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 2ced2f1db7bb..c2e26819bcaf 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -54,6 +54,7 @@ struct bmac_data { int rx_dma_intr; volatile struct dbdma_cmd *tx_cmds; /* xmit dma command list */ volatile struct dbdma_cmd *rx_cmds; /* recv dma command list */ + struct device_node *node; struct sk_buff *rx_bufs[N_RX_RING]; int rx_fill; int rx_empty; @@ -235,11 +236,11 @@ bmac_reset_chip(struct device *dev) dbdma_reset(rd); dbdma_reset(td); - feature_set(FEATURE_BMac_IO_enable); + feature_set(bp->node, FEATURE_BMac_IO_enable); udelay(10000); - feature_set(FEATURE_BMac_reset); + feature_set(bp->node, FEATURE_BMac_reset); udelay(10000); - feature_clear(FEATURE_BMac_reset); + feature_clear(bp->node, FEATURE_BMac_reset); udelay(10000); } @@ -374,8 +375,6 @@ bmac_init_registers(struct device *dev) //bmwrite(dev, TXCFG, TxMACEnable); /* TxNeverGiveUp maybe later */ bmread(dev, STATUS); /* read it just to clear it */ - bmwrite(dev, INTDISABLE, EnableNormal); - /* zero out the chip Hash Filter registers */ for (i=0; i<4; i++) bp->hash_table_mask[i] = 0; bmwrite(dev, BHASH3, bp->hash_table_mask[0]); /* bits 15 - 0 */ @@ -387,10 +386,11 @@ bmac_init_registers(struct device *dev) bmwrite(dev, MADD0, *pWord16++); bmwrite(dev, MADD1, *pWord16++); bmwrite(dev, MADD2, *pWord16); - bmwrite(dev, RXCFG, RxCRCNoStrip | RxHashFilterEnable | RxRejectOwnPackets); - + + bmwrite(dev, INTDISABLE, EnableNormal); + return; } @@ -620,6 +620,8 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct device *dev) bp->tx_bufs[bp->tx_fill] = skb; bp->tx_fill = i; + bp->stats.tx_bytes += skb->len; + dbdma_continue(td); return 0; @@ -669,6 +671,7 @@ static void bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) skb_reserve(bp->rx_bufs[i], 2); bmac_construct_rxbuff(bp->rx_bufs[i]->data, &bp->rx_cmds[i]); ++bp->stats.rx_packets; + bp->stats.rx_bytes += nb; } else { ++bp->stats.rx_dropped; } @@ -1241,7 +1244,7 @@ bmac_probe(struct device *dev) dev->base_addr = bmacs->addrs[0].address; dev->irq = bmacs->intrs[0].line; - + bmwrite(dev, INTDISABLE, DisableAll); addr = get_property(bmacs, "mac-address", NULL); @@ -1288,6 +1291,7 @@ bmac_probe(struct device *dev) bp->queue = (struct sk_buff_head *)(bp->rx_cmds + N_RX_RING + 1); skb_queue_head_init(bp->queue); + bp->node = bmacs; memset(&bp->stats, 0, sizeof(bp->stats)); memset((char *) bp->tx_cmds, 0, (N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd)); diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 1c2534328cc2..ce5846bdbcc9 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -56,7 +56,6 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (4*HZ) -#include #ifdef MODULE #ifdef MODVERSIONS #include diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index fec55899f635..3411fd1892d6 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -63,7 +63,6 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT ((2000*HZ)/1000) -#include #ifdef MODULE #ifdef MODVERSIONS #include diff --git a/drivers/pci/pcisyms.c b/drivers/pci/pcisyms.c index 0297d8b0f7c6..f7399c9fb6ce 100644 --- a/drivers/pci/pcisyms.c +++ b/drivers/pci/pcisyms.c @@ -6,6 +6,7 @@ * Copyright 1998 Martin Mares */ +#include #include #include diff --git a/drivers/scsi/ChangeLog.ncr53c8xx b/drivers/scsi/ChangeLog.ncr53c8xx index bd302921fc21..c3a2550d198f 100644 --- a/drivers/scsi/ChangeLog.ncr53c8xx +++ b/drivers/scsi/ChangeLog.ncr53c8xx @@ -1,3 +1,9 @@ +Wed Nov 11 10:00 1998 Gerard Roudier (groudier@club-internet.fr) + * revision 3.1b + - The driver was unhappy when configured with default_tags > MAX_TAGS + Hopefully doubly-fixed. + - Update the Configure.help driver section that speaks of TAGS. + Wed Oct 21 21:00 1998 Gerard Roudier (groudier@club-internet.fr) * revision 3.1a - Changes from Eddie Dost for Sparc and Alpha: diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in index 2cfe9a6e73d8..0bd37f65f27f 100644 --- a/drivers/scsi/Config.in +++ b/drivers/scsi/Config.in @@ -80,7 +80,7 @@ fi if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_NCR53C7xx" != "y" ]; then dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then - int ' default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 4 + int ' default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8 int ' maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32 int ' synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20 bool ' enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index 3ce90a63d96a..f17f0bdd5248 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c @@ -88,7 +88,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index 5876f4e24c70..c08589b58836 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -222,6 +223,13 @@ mesh_detect(Scsi_Host_Template *tp) struct Scsi_Host *mesh_host; void *dma_cmd_space; + if (_machine == _MACH_Pmac) { + use_active_neg = (find_devices("mac-io") ? 0 : SEQ_ACTIVE_NEG); + } else { + /* CHRP mac-io */ + use_active_neg = SEQ_ACTIVE_NEG; + } + nmeshes = 0; prev_statep = &all_meshes; /* @@ -245,7 +253,7 @@ mesh_detect(Scsi_Host_Template *tp) } mesh_host->unique_id = nmeshes; note_scsi_host(mesh, mesh_host); - + ms = (struct mesh_state *) mesh_host->hostdata; if (ms == 0) panic("no mesh state"); @@ -281,10 +289,6 @@ mesh_detect(Scsi_Host_Template *tp) *prev_statep = ms; prev_statep = &ms->next; - if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) { - printk(KERN_ERR "MESH: can't get irq %d\n", ms->meshintr); - } - if ((cfp = (int *) get_property(mesh, "clock-frequency", NULL))) { ms->clk_freq = *cfp; @@ -298,18 +302,20 @@ mesh_detect(Scsi_Host_Template *tp) if (mesh_sync_period < minper) mesh_sync_period = minper; + feature_set(mesh, FEATURE_MESH_enable); + mdelay(200); + mesh_init(ms); + if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) { + printk(KERN_ERR "MESH: can't get irq %d\n", ms->meshintr); + } + ++nmeshes; } - if (_machine == _MACH_Pmac) { - use_active_neg = (find_devices("mac-io") ? 0 : SEQ_ACTIVE_NEG); - if (nmeshes > 0) + + if ((_machine == _MACH_Pmac) && (nmeshes > 0)) register_reboot_notifier(&mesh_notifier); - } else { - /* CHRP mac-io */ - use_active_neg = SEQ_ACTIVE_NEG; - } return nmeshes; } @@ -467,12 +473,27 @@ mesh_init(struct mesh_state *ms) volatile struct mesh_regs *mr = ms->mesh; volatile struct dbdma_regs *md = ms->dma; - out_8(&mr->interrupt, 0xff); /* clear all interrupt bits */ + udelay(100); + + out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16); /* stop dma */ + out_8(&mr->exception, 0xff); /* clear all exception bits */ + out_8(&mr->error, 0xff); /* clear all error bits */ + out_8(&mr->sequence, SEQ_RESETMESH); + udelay(10); out_8(&mr->intr_mask, INT_ERROR | INT_EXCEPTION | INT_CMDDONE); out_8(&mr->source_id, ms->host->this_id); out_8(&mr->sel_timeout, 25); /* 250ms */ - out_8(&mr->sync_params, ASYNC_PARAMS); /* asynchronous initially */ - out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + out_8(&mr->sync_params, ASYNC_PARAMS); + + out_8(&mr->bus_status1, BS1_RST); /* assert RST */ + udelay(30); /* leave it on for >= 25us */ + out_8(&mr->bus_status1, 0); /* negate RST */ + + out_8(&mr->sequence, SEQ_FLUSHFIFO); + udelay(1); + out_8(&mr->sync_params, ASYNC_PARAMS); + out_8(&mr->sequence, SEQ_ENBRESEL); + out_8(&mr->interrupt, 0xff); /* clear all interrupt bits */ } /* diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 5f632df09644..dbfe1b177676 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -73,7 +73,7 @@ */ /* -** October 21 1998, version 3.1a +** November 11 1998, version 3.1b ** ** Supported SCSI-II features: ** Synchronous negotiation @@ -4319,7 +4319,7 @@ static int ncr_prepare_setting(ncb_p np, ncr_nvram *nvram) #endif tp->usrsync = driver_setup.default_sync; tp->usrwide = driver_setup.max_wide; - tp->usrtags = driver_setup.default_tags; + tp->usrtags = SCSI_NCR_MAX_TAGS; if (!driver_setup.disconnection) np->target[i].usrflag = UF_NODISC; } @@ -8207,6 +8207,12 @@ static ccb_p ncr_get_ccb (ncb_p np, u_char tn, u_char ln) */ if (lp) { XPT_QUEHEAD *qp; + /* + ** Keep from using more tags than we can handle. + */ + if (lp->usetags && lp->busyccbs >= lp->maxnxs) + return (ccb_p) 0; + /* ** Allocate a new CCB if needed. */ @@ -10072,19 +10078,20 @@ static void ncr53c8xx_select_queue_depths(struct Scsi_Host *host, struct scsi_de lp = tp->lp[device->lun]; /* - ** Donnot use more than our maximum. ** Select queue depth from driver setup. ** Donnot use more than configured by user. ** Use 2 for devices that donnot support tags. ** Use at least 2. + ** Donnot use more than our maximum. */ - device->queue_depth = SCSI_NCR_MAX_TAGS; device->queue_depth = device_queue_depth(np, device->id, device->lun); if (device->queue_depth > tp->usrtags) device->queue_depth = tp->usrtags; if (!device->tagged_supported || device->queue_depth < 2) device->queue_depth = 2; + if (device->queue_depth > SCSI_NCR_MAX_TAGS) + device->queue_depth = SCSI_NCR_MAX_TAGS; /* ** Since the queue depth is not tunable under Linux, diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h index 93b17aa6f07e..8c513279b7d7 100644 --- a/drivers/scsi/ncr53c8xx.h +++ b/drivers/scsi/ncr53c8xx.h @@ -45,7 +45,7 @@ /* ** Name and revision of the driver */ -#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 3.1a" +#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 3.1b" /* ** Check supported Linux versions diff --git a/drivers/sound/dmasound.c b/drivers/sound/dmasound.c index 56aa9e9992c3..aaf21e2bad40 100644 --- a/drivers/sound/dmasound.c +++ b/drivers/sound/dmasound.c @@ -107,18 +107,17 @@ History: #include #include #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC #include #include #include -#ifdef CONFIG_PMAC_PBOOK #include +#include #include -#endif /* CONFIG_PMAC_PBOOK */ #include "awacs_defs.h" #include #include -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ #include "dmasound.h" #include @@ -165,7 +164,7 @@ extern u_short amiga_audio_period; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC /* * Interrupt numbers and addresses, obtained from the device tree. */ @@ -174,6 +173,8 @@ static volatile struct awacs_regs *awacs; static volatile struct dbdma_regs *awacs_txdma, *awacs_rxdma; static int awacs_rate_index; static int awacs_subframe; +static int awacs_revision; +static int awacs_spkr_vol; /* * Space for the DBDMA command blocks. @@ -249,7 +250,7 @@ struct notifier_block awacs_sleep_notifier = { }; #endif /* CONFIG_PMAC_PBOOK */ -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ /*** Some declarations *******************************************************/ @@ -587,7 +588,7 @@ static ssize_t ami_ct_u16le(const u_char *userPtr, size_t userCount, ssize_t frameLeft); #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); @@ -618,7 +619,7 @@ static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount, static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ /*** Machine definitions *****************************************************/ @@ -675,7 +676,7 @@ struct sound_settings { int treble; int gain; int minDev; /* minor device number currently open */ -#if defined(CONFIG_ATARI) || defined(CONFIG_PMAC) +#if defined(CONFIG_ATARI) || defined(CONFIG_PPC) int bal; /* balance factor for expanding (not volume!) */ u_long data; /* data for expanding */ #endif /* CONFIG_ATARI */ @@ -724,7 +725,7 @@ static void AmiPlay(void); static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp); #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC static void *PMacAlloc(unsigned int size, int flags) __init; static void PMacFree(void *ptr, unsigned int size) __init; static int PMacIrqInit(void) __init; @@ -743,7 +744,7 @@ static int awacs_get_volume(int reg, int lshift); static int awacs_volume_setter(int volume, int n, int mute, int lshift); static void awacs_mksound(unsigned int hz, unsigned int ticks); static void awacs_nosound(unsigned long xx); -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ /*** Mid level stuff *********************************************************/ @@ -1777,7 +1778,7 @@ static ssize_t ami_ct_u16le(const u_char *userPtr, size_t userCount, } #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) @@ -2161,7 +2162,7 @@ static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount, return stereo? utotal * 4: utotal * 2; } -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ #ifdef CONFIG_ATARI @@ -2191,7 +2192,7 @@ static TRANS transAmiga = { }; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC static TRANS transAwacsNormal = { pmac_ct_law, pmac_ct_law, pmac_ct_s8, pmac_ct_u8, pmac_ct_s16, pmac_ct_u16, pmac_ct_s16, pmac_ct_u16 @@ -2201,7 +2202,7 @@ static TRANS transAwacsExpand = { pmac_ctx_law, pmac_ctx_law, pmac_ctx_s8, pmac_ctx_u8, pmac_ctx_s16, pmac_ctx_u16, pmac_ctx_s16, pmac_ctx_u16 }; -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ /*** Low level stuff *********************************************************/ @@ -2971,7 +2972,7 @@ static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp) } #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC /* * PCI PowerMac, with AWACS and DBDMA. @@ -3226,7 +3227,7 @@ awacs_write(int val) { while (in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) ; /* XXX should have timeout */ - out_le32(&awacs->codec_ctrl, val); + out_le32(&awacs->codec_ctrl, val | (awacs_subframe << 22)); } static void awacs_nosound(unsigned long xx) @@ -3343,7 +3344,38 @@ static int awacs_sleep_notify(struct notifier_block *this, } #endif /* CONFIG_PMAC_PBOOK */ -#endif /* CONFIG_PMAC */ +/* Turn on sound output, needed on G3 desktop powermacs */ +static void +awacs_enable_amp(int spkr_vol) +{ + struct adb_request req; + + awacs_spkr_vol = spkr_vol; + if (adb_hardware != ADB_VIACUDA) + return; + + /* turn on headphones */ + cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, + 0x8a, 4, 0); + while (!req.complete) cuda_poll(); + cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, + 0x8a, 6, 0); + while (!req.complete) cuda_poll(); + + /* turn on speaker */ + cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, + 0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100); + while (!req.complete) cuda_poll(); + cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, + 0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100); + while (!req.complete) cuda_poll(); + + cuda_request(&req, NULL, 5, CUDA_PACKET, + CUDA_GET_SET_IIC, 0x8a, 1, 0x29); + while (!req.complete) cuda_poll(); +} + +#endif /* CONFIG_PPC */ /*** Machine definitions *****************************************************/ @@ -3382,7 +3414,7 @@ static MACHINE machAmiga = { }; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC static MACHINE machPMac = { DMASND_AWACS, PMacAlloc, PMacFree, PMacIrqInit, #ifdef MODULE @@ -3683,7 +3715,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, break; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC case DMASND_AWACS: switch (cmd) { case SOUND_MIXER_READ_DEVMASK: @@ -3733,12 +3765,18 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_volume(data)); case SOUND_MIXER_READ_SPEAKER: - data = (awacs_reg[1] & MASK_CMUTE)? 0: - awacs_get_volume(awacs_reg[4], 6); + if (awacs_revision >= 3 && adb_hardware == ADB_VIACUDA) + data = awacs_spkr_vol; + else + data = (awacs_reg[1] & MASK_CMUTE)? 0: + awacs_get_volume(awacs_reg[4], 6); return IOCTL_OUT(arg, data); case SOUND_MIXER_WRITE_SPEAKER: IOCTL_IN(arg, data); - data = awacs_volume_setter(data, 4, MASK_CMUTE, 6); + if (awacs_revision >= 3 && adb_hardware == ADB_VIACUDA) + awacs_enable_amp(data); + else + data = awacs_volume_setter(data, 4, MASK_CMUTE, 6); return IOCTL_OUT(arg, data); case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */ IOCTL_IN(arg, data); @@ -3862,10 +3900,10 @@ __initfunc(static void mixer_init(void)) static void sq_setup(int numBufs, int bufSize, char **buffers) { -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC int i; volatile struct dbdma_cmd *cp; -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ sq.max_count = numBufs; sq.max_active = numBufs; @@ -3887,7 +3925,7 @@ static void sq_setup(int numBufs, int bufSize, char **buffers) sq.block_size_half = sq.block_size>>1; sq.block_size_quarter = sq.block_size_half>>1; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC cp = awacs_tx_cmds; memset((void *) cp, 0, (numBufs + 1) * sizeof(struct dbdma_cmd)); for (i = 0; i < numBufs; ++i, ++cp) { @@ -3897,7 +3935,7 @@ static void sq_setup(int numBufs, int bufSize, char **buffers) st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds)); out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds)); -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ } static void sq_play(void) @@ -4206,11 +4244,11 @@ __initfunc(static void sq_init(void)) sound.dsp.speed = 8000; break; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC case DMASND_AWACS: sound.dsp.speed = 8000; break; -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ } /* before the first open to /dev/dsp this wouldn't be set */ @@ -4251,11 +4289,11 @@ static int state_open(struct inode *inode, struct file *file) mach = "Amiga "; break; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC case DMASND_AWACS: mach = "PowerMac "; break; -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ } len += sprintf(buffer+len, "%sDMA sound driver:\n", mach); @@ -4396,7 +4434,7 @@ __initfunc(void dmasound_init(void)) { int has_sound = 0; int i; -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC struct device_node *np; #endif @@ -4430,7 +4468,7 @@ __initfunc(void dmasound_init(void)) } #endif /* __mc68000__ */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC awacs_subframe = 0; np = find_devices("awacs"); if (np == 0) { @@ -4479,6 +4517,13 @@ __initfunc(void dmasound_init(void)) awacs_write(awacs_reg[2] + MASK_ADDR2); awacs_write(awacs_reg[4] + MASK_ADDR4); + /* Initialize recent versions of the awacs */ + awacs_revision = (in_le32(&awacs->codec_stat) >> 12) & 0xf; + if (awacs_revision >= 3) { + awacs_write(0x6000); + awacs_enable_amp(100 * 0x101); + } + /* Initialize beep stuff */ beep_dbdma_cmd = awacs_tx_cmds + (numBufs + 1); orig_mksound = kd_mksound; @@ -4492,7 +4537,7 @@ __initfunc(void dmasound_init(void)) &awacs_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ } -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ if (!has_sound) return; diff --git a/drivers/video/cvppcfb.c b/drivers/video/cvppcfb.c index a41cd0cb25a3..3e786ab61359 100644 --- a/drivers/video/cvppcfb.c +++ b/drivers/video/cvppcfb.c @@ -14,6 +14,7 @@ * for more details. */ +#include #include #include #include diff --git a/fs/exec.c b/fs/exec.c index b18493bb6568..38afa143ffe9 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -22,6 +22,7 @@ * formats. */ +#include #include #include #include diff --git a/fs/hfs/ChangeLog b/fs/hfs/ChangeLog index 2a30395e9df9..3015bd4f589f 100644 --- a/fs/hfs/ChangeLog +++ b/fs/hfs/ChangeLog @@ -1,3 +1,9 @@ +1998-11-12 a sun + + * extent.c (shrink_fork): added some lock_bitmap/unlock_bitmap's + to protect hfs_clear_vbm_bits. we should no longer have problems + with free_ablocks wrapping around. + 1998-11-02 a sun * mdb.c (hfs_mdb_get): plugged up an mdb failed initialization diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 5aa7353883f8..900bddf3398a 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c @@ -176,6 +176,14 @@ struct hfs_btree * hfs_btree_init(struct hfs_mdb *mdb, ino_t cnid, bt->wait = NULL; bt->dirt = 0; memset(bt->cache, 0, sizeof(bt->cache)); + +#if 0 /* this is a fake entry. so we don't need to initialize it. */ + memset(&bt->entry, 0, sizeof(bt->entry)); + hfs_init_waitqueue(&bt->entry.wait); + INIT_LIST_HEAD(&bt->entry.hash); + INIT_LIST_HEAD(&bt->entry.list); +#endif + bt->entry.mdb = mdb; bt->entry.cnid = cnid; bt->entry.type = HFS_CDR_FIL; diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index 7e0f8700d487..1fc749f344eb 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -487,6 +487,7 @@ static void shrink_fork(struct hfs_fork *fork, int ablocks) if ((count = next + 1 - ablocks) > 0) { for (i=2; (i>=0) && !ext->length[i]; --i) {}; + lock_bitmap(mdb); while (count && (ext->length[i] <= count)) { ext->end -= ext->length[i]; count -= ext->length[i]; @@ -509,6 +510,7 @@ static void shrink_fork(struct hfs_fork *fork, int ablocks) "blocks.\n", error); } } + unlock_bitmap(mdb); update_ext(fork, ext); } @@ -612,7 +614,9 @@ more_extents: } else { if (!(ext = new_extent(fork, ext, blocks/ablksz, start, len, ablksz))) { + lock_bitmap(mdb); hfs_clear_vbm_bits(mdb, start, len); + unlock_bitmap(mdb); return; } } diff --git a/fs/hfs/file_hdr.c b/fs/hfs/file_hdr.c index 09675d8ab38d..3ae2d5b5d0f0 100644 --- a/fs/hfs/file_hdr.c +++ b/fs/hfs/file_hdr.c @@ -937,7 +937,7 @@ static void hdr_truncate(struct inode *inode) if (fork->lsize != descr->length) { fork->lsize = descr->length; hfs_extent_adj(fork); - hfs_cat_mark_dirty(HFS_I(inode)->entry); + hfs_cat_mark_dirty(entry); } } } diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index 9319fb3cd5d2..c7267373199b 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c @@ -260,6 +260,9 @@ void hfs_mdb_commit(struct hfs_mdb *mdb, int backup) hfs_put_hl(mdb->file_count, raw->drFilCnt); hfs_put_hl(mdb->dir_count, raw->drDirCnt); + /* write MDB to disk */ + hfs_buffer_dirty(mdb->buf); + /* write the backup MDB, not returning until it is written. * we only do this when either the catalog or extents overflow * files grow. */ diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index 25e2204b4a18..3409954bed5b 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -7,6 +7,7 @@ #define __NO_VERSION__ +#include #include #include diff --git a/fs/nfs/write.c b/fs/nfs/write.c index e5ec43f05612..1aeecf950f18 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -46,7 +46,6 @@ * Copyright (C) 1996, 1997, Olaf Kirch */ -#include #include #include #include @@ -332,8 +331,6 @@ create_write_request(struct dentry *dentry, struct inode *inode, wreq->wb_bytes = bytes; wreq->wb_count = 2; /* One for the IO, one for us */ - atomic_inc(&page->count); - append_write_request(&NFS_WRITEBACK(inode), wreq); if (nr_write_requests++ > NFS_WRITEBACK_MAX*3/4) @@ -480,8 +477,7 @@ nfs_updatepage(struct file *file, struct page *page, unsigned long offset, unsig /* * Ok, there's another user of this page with the new request.. - * Increment the usage count, and schedule the request (the - * end of the request will drop the usage count..) + * The IO completion will then free the page. */ atomic_inc(&page->count); diff --git a/fs/proc/fd.c b/fs/proc/fd.c index 5409e2d671aa..8db99f7f4d80 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -119,6 +119,7 @@ static int proc_lookupfd(struct inode * dir, struct dentry * dentry) ino = (pid << 16) + PROC_PID_FD_DIR + fd; inode = proc_get_inode(dir->i_sb, ino, NULL); if (inode) { + dentry->d_op = &proc_dentry_operations; d_add(dentry, inode); err = 0; } diff --git a/fs/qnx4/symlinks.c b/fs/qnx4/symlinks.c index 2fb7c748e79f..36679c52a575 100644 --- a/fs/qnx4/symlinks.c +++ b/fs/qnx4/symlinks.c @@ -13,7 +13,6 @@ /* THIS FILE HAS TO BE REWRITTEN */ -#include #include #include #include diff --git a/fs/super.c b/fs/super.c index be5294f2f166..2784d6462019 100644 --- a/fs/super.c +++ b/fs/super.c @@ -17,6 +17,7 @@ * Added change_root: Werner Almesberger & Hans Lermen, Feb '96 */ +#include #include #include #include diff --git a/include/asm-ppc/adb.h b/include/asm-ppc/adb.h index 540bb24372d2..58fcb8abe550 100644 --- a/include/asm-ppc/adb.h +++ b/include/asm-ppc/adb.h @@ -46,7 +46,7 @@ extern enum adb_hw { } adb_hardware; extern int (*adb_send_request)(struct adb_request *req, int sync); -extern int (*adb_autopoll)(int on); +extern int (*adb_autopoll)(int devs); extern int (*adb_reset_bus)(void); /* Values for adb_request flags */ diff --git a/include/asm-ppc/amigappc.h b/include/asm-ppc/amigappc.h index e3abe6809fef..5546cb1fbd5b 100644 --- a/include/asm-ppc/amigappc.h +++ b/include/asm-ppc/amigappc.h @@ -14,17 +14,33 @@ #ifndef _M68K_AMIGAPPC_H #define _M68K_AMIGAPPC_H +#ifndef __ASSEMBLY__ + +#ifndef iobarrier /* Don't include io.h - avoid circular dependency */ +#define iobarrier() eieio() +#endif + +#define APUS_WRITE(_a_, _v_) \ +do { \ + (*((volatile unsigned char *)(_a_)) = (_v_)); \ + iobarrier (); \ +} while (0) + +#define APUS_READ(_a_, _v_) \ +do { \ + (_v_) = (*((volatile unsigned char *)(_a_))); \ + iobarrier (); \ +} while (0) +#endif /* ndef __ASSEMBLY__ */ + /* Maybe add a [#ifdef WANT_ZTWOBASE] condition to amigahw.h? */ #define zTwoBase (0x80000000) -/* At CYBERBASEp we'll find the following sum: +/* At CYBERBASEp we find the following sum: * -KERNELBASE+CyberStormMemoryBase */ #define CYBERBASEp (0xfff00000) -#define APUS_WRITE(a,v) (*((volatile unsigned char *)a) = v) -#define APUS_READ(a) (*((volatile unsigned char *)a)) - #define APUS_IPL_BASE (zTwoBase + 0x00f60000) #define APUS_REG_RESET (APUS_IPL_BASE + 0x00) #define APUS_REG_WAITSTATE (APUS_IPL_BASE + 0x10) @@ -32,6 +48,7 @@ #define APUS_REG_LOCK (APUS_IPL_BASE + 0x20) #define APUS_REG_INT (APUS_IPL_BASE + 0x28) #define APUS_IPL_EMU (APUS_IPL_BASE + 0x30) +#define APUS_INT_LVL (APUS_IPL_BASE + 0x38) #define REGSHADOW_SETRESET (0x80) #define REGSHADOW_SELFRESET (0x40) @@ -66,4 +83,7 @@ #define IPLEMU_PPCIPL0 (0x01) #define IPLEMU_IPLMASK (IPLEMU_PPCIPL2|IPLEMU_PPCIPL1|IPLEMU_PPCIPL0) +#define INTLVL_SETRESET (0x80) +#define INTLVL_MASK (0x7f) + #endif /* _M68k_AMIGAPPC_H */ diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h index bd55a65da49d..8560c7d882c2 100644 --- a/include/asm-ppc/dma.h +++ b/include/asm-ppc/dma.h @@ -8,6 +8,8 @@ #include #include +#include +#include /* * Note: Adapted for PowerPC by Gary Thomas @@ -203,6 +205,20 @@ extern long ppc_cs4232_dma, ppc_cs4232_dma2; #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + /* enable/disable a specific DMA channel */ static __inline__ void enable_dma(unsigned int dmanr) { diff --git a/include/asm-ppc/feature.h b/include/asm-ppc/feature.h new file mode 100644 index 000000000000..4264690f85c7 --- /dev/null +++ b/include/asm-ppc/feature.h @@ -0,0 +1,65 @@ +/* + * Definitions for accessing the Feature Control Register (FCR) + * on Power Macintoshes and similar machines. The FCR lets us + * enable/disable, reset, and power up/down various peripherals. + * + * 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. + * + * Copyright (C) 1998 Paul Mackerras. + */ +#ifndef __ASM_PPC_FEATURE_H +#define __ASM_PPC_FEATURE_H + +/* + * The FCR bits for particular features vary somewhat between + * different machines. So we abstract a list of features here + * and let the feature_* routines map them to the actual bits. + */ +enum system_feature { + FEATURE_null, + FEATURE_Serial_reset, + FEATURE_Serial_enable, + FEATURE_Serial_IO_A, + FEATURE_Serial_IO_B, + FEATURE_SWIM3_enable, + FEATURE_MESH_enable, + FEATURE_IDE_enable, + FEATURE_VIA_enable, + FEATURE_CD_power, + FEATURE_Mediabay_reset, + FEATURE_Mediabay_enable, + FEATURE_Mediabay_PCI_enable, + FEATURE_Mediabay_IDE_enable, + FEATURE_Mediabay_floppy_enable, + FEATURE_BMac_reset, + FEATURE_BMac_IO_enable, + FEATURE_Modem_PowerOn, + FEATURE_Modem_Reset, + FEATURE_last, +}; + +/* Note about the device parameter: Each device gives it's own entry. If NULL, + the feature function will just do nothing and return -EINVAL. + The feature management will walk up the device tree until in reaches a recognized + chip for which features can be changed and it will then apply the necessary + features to that chip. If it's not found, -ENODEV is returned. + Note also that feature_test/set/clear are interrupt-safe provided that they are + called _after_ feature_init() is completed. + */ + +/* Test whether a particular feature is enabled. May return -ENODEV*/ +extern int feature_test(struct device_node* device, enum system_feature f); + +/* Set a particular feature. Returns 0 or -ENODEV */ +extern int feature_set(struct device_node* device, enum system_feature f); + +/* Clear a particular feature */ +extern int feature_clear(struct device_node* device, enum system_feature f); + +/* Initialize feature stuff */ +extern void feature_init(void); + + +#endif /* __ASM_PPC_FEATURE_H */ diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h index 566fc0af125c..75f77641caba 100644 --- a/include/asm-ppc/ide.h +++ b/include/asm-ppc/ide.h @@ -42,6 +42,7 @@ void ide_outsw(ide_ioreg_t port, void *buf, int ns); #ifdef __KERNEL__ +#include #include #include /* so we can redefine insw/outsw */ @@ -98,9 +99,11 @@ static __inline__ int ide_default_irq(ide_ioreg_t base) static __inline__ ide_ioreg_t ide_default_io_base(int index) { +#if defined(CONFIG_BLK_DEV_IDE_PMAC) if (_machine == _MACH_Pmac) { return pmac_ide_regbase[index]; } +#endif if (_machine == _MACH_mbx) return index; if ( _machine == _MACH_chrp ) { if (chrp_ide_ports_known == 0) @@ -138,13 +141,76 @@ static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent release_region(from, extent); } -#define ide_fix_driveid(id) do { \ - int nh; \ - unsigned short *p = (unsigned short *) id; \ - if (( _machine == _MACH_Pmac ) || (_machine == _MACH_chrp)|| (_machine == _MACH_mbx) ) \ - for (nh = SECTOR_WORDS * 2; nh != 0; --nh, ++p) \ - *p = (*p << 8) + (*p >> 8); \ -} while (0) +/* Convert the shorts/longs in hd_driveid from little to big endian; + chars are endian independant, of course, but strings need to be flipped. + (Despite what it says in drivers/block/ide.h, they come up as little endian...) + Changes to linux/hdreg.h may require changes here. */ +static __inline__ void ide_fix_driveid (struct hd_driveid *id) { + if (( _machine == _MACH_Pmac ) || (_machine == _MACH_chrp)|| (_machine == _MACH_mbx) ) { + int i; + unsigned short *stringcast; + id->config = __le16_to_cpu(id->config); + id->cyls = __le16_to_cpu(id->cyls); + id->reserved2 = __le16_to_cpu(id->reserved2); + id->heads = __le16_to_cpu(id->heads); + id->track_bytes = __le16_to_cpu(id->track_bytes); + id->sector_bytes = __le16_to_cpu(id->sector_bytes); + id->sectors = __le16_to_cpu(id->sectors); + id->vendor0 = __le16_to_cpu(id->vendor0); + id->vendor1 = __le16_to_cpu(id->vendor1); + id->vendor2 = __le16_to_cpu(id->vendor2); + stringcast = (unsigned short *)&id->serial_no[0]; + for (i=0; i<(20/2); i++) + stringcast[i] = __le16_to_cpu(stringcast[i]); + id->buf_type = __le16_to_cpu(id->buf_type); + id->buf_size = __le16_to_cpu(id->buf_size); + id->ecc_bytes = __le16_to_cpu(id->ecc_bytes); + stringcast = (unsigned short *)&id->fw_rev[0]; + for (i=0; i<(8/2); i++) + stringcast[i] = __le16_to_cpu(stringcast[i]); + stringcast = (unsigned short *)&id->model[0]; + for (i=0; i<(40/2); i++) + stringcast[i] = __le16_to_cpu(stringcast[i]); + id->dword_io = __le16_to_cpu(id->dword_io); + id->reserved50 = __le16_to_cpu(id->reserved50); + id->field_valid = __le16_to_cpu(id->field_valid); + id->cur_cyls = __le16_to_cpu(id->cur_cyls); + id->cur_heads = __le16_to_cpu(id->cur_heads); + id->cur_sectors = __le16_to_cpu(id->cur_sectors); + id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0); + id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1); + id->lba_capacity = __le32_to_cpu(id->lba_capacity); + id->dma_1word = __le16_to_cpu(id->dma_1word); + id->dma_mword = __le16_to_cpu(id->dma_mword); + id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes); + id->eide_dma_min = __le16_to_cpu(id->eide_dma_min); + id->eide_dma_time = __le16_to_cpu(id->eide_dma_time); + id->eide_pio = __le16_to_cpu(id->eide_pio); + id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy); + id->word69 = __le16_to_cpu(id->word69); + id->word70 = __le16_to_cpu(id->word70); + id->word71 = __le16_to_cpu(id->word71); + id->word72 = __le16_to_cpu(id->word72); + id->word73 = __le16_to_cpu(id->word73); + id->word74 = __le16_to_cpu(id->word74); + id->word75 = __le16_to_cpu(id->word75); + id->word76 = __le16_to_cpu(id->word76); + id->word77 = __le16_to_cpu(id->word77); + id->word78 = __le16_to_cpu(id->word78); + id->word79 = __le16_to_cpu(id->word79); + id->word80 = __le16_to_cpu(id->word80); + id->word81 = __le16_to_cpu(id->word81); + id->word82 = __le16_to_cpu(id->word82); + id->word83 = __le16_to_cpu(id->word83); + id->word84 = __le16_to_cpu(id->word84); + id->word85 = __le16_to_cpu(id->word85); + id->word86 = __le16_to_cpu(id->word86); + id->word87 = __le16_to_cpu(id->word87); + id->dma_ultra = __le16_to_cpu(id->dma_ultra); + for (i=0; i<167; i++) + id->reserved[i] = __le16_to_cpu(id->reserved[i]); + } +} #undef insw diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index 8c3eade019df..da5219e397a2 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -49,18 +49,18 @@ extern unsigned long pci_dram_offset; #endif /* CONFIG_APUS */ #endif /* CONFIG_MBX8xx */ -#define readb(addr) (*(volatile unsigned char *) (addr)) -#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b)) +#define readb(addr) in_8((volatile unsigned char *)(addr)) +#define writeb(b,addr) out_8((volatile unsigned char *)(addr), (b)) #if defined(CONFIG_APUS) #define readw(addr) (*(volatile unsigned short *) (addr)) #define readl(addr) (*(volatile unsigned int *) (addr)) #define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b)) #define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b)) #else -#define readw(addr) ld_le16((volatile unsigned short *)(addr)) -#define readl(addr) ld_le32((volatile unsigned *)addr) -#define writew(b,addr) st_le16((volatile unsigned short *)(addr),(b)) -#define writel(b,addr) st_le32((volatile unsigned *)(addr),(b)) +#define readw(addr) in_le16((volatile unsigned short *)(addr)) +#define readl(addr) in_le32((volatile unsigned *)addr) +#define writew(b,addr) out_le16((volatile unsigned short *)(addr),(b)) +#define writel(b,addr) out_le32((volatile unsigned *)(addr),(b)) #endif #define insb(port, buf, ns) _insb((unsigned char *)((port)+_IO_BASE), (buf), (ns)) @@ -123,6 +123,7 @@ extern void _outsl_ns(volatile unsigned long *port, const void *buf, int nl); extern void *__ioremap(unsigned long address, unsigned long size, unsigned long flags); extern void *ioremap(unsigned long address, unsigned long size); +#define ioremap_nocache(addr, size) ioremap((addr), (size)) extern void iounmap(void *addr); extern unsigned long iopa(unsigned long addr); #ifdef CONFIG_APUS @@ -180,22 +181,6 @@ extern inline void * phys_to_virt(unsigned long address) #endif } -static inline int check_signature(unsigned long io_addr, - const unsigned char *signature, int length) -{ - int retval = 0; - do { - if (readb(io_addr) != *signature) - goto out; - io_addr++; - signature++; - length--; - } while (length); - retval = 1; -out: - return retval; -} - #endif /* __KERNEL__ */ /* @@ -207,6 +192,7 @@ extern inline void eieio(void) { __asm__ __volatile__ ("eieio" : : : "memory"); } +#define iobarrier() eieio() /* * 8, 16 and 32 bit, big and little endian I/O operations, with barrier. @@ -280,4 +266,22 @@ extern inline void out_be32(volatile unsigned *addr, int val) __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val)); } +#ifdef __KERNEL__ +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index bf9d07306eee..661b2c0078d8 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -20,7 +20,8 @@ * so it is the max of them all - which happens to be powermac * at present (G3 powermacs have 64). */ -#define NR_IRQS 64 +#define NR_IRQS 128 + #endif /* CONFIG_APUS */ #define NUM_8259_INTERRUPTS 16 diff --git a/include/asm-ppc/mediabay.h b/include/asm-ppc/mediabay.h index 85146e69ae89..04792d15ed50 100644 --- a/include/asm-ppc/mediabay.h +++ b/include/asm-ppc/mediabay.h @@ -14,20 +14,15 @@ #ifdef __KERNEL__ void media_bay_init(void); -int check_media_bay(int what); -int media_bay_task(void *); +int check_media_bay(struct device_node *which_bay, int what); +int check_media_bay_by_base(unsigned long base, int what); -extern int media_bay_present; /* 1 if this machine has a media bay */ +/* Number of bays in the machine or 0 */ +extern int media_bay_count; -/* - * The following give information about the IDE interface - * of the media bay: the base virtual address and IRQ number, - * and the index that the IDE driver has assigned to it - * (or -1 if it is not currently registered with the driver). - */ -extern unsigned long mb_cd_base; -extern int mb_cd_irq; -extern int mb_cd_index; +/* called by pmac-ide.c to register IDE controller for media bay */ +extern int media_bay_set_ide_infos(struct device_node* which_bay, + unsigned long base, int irq, int index); #endif /* __KERNEL__ */ #endif /* _PPC_MEDIABAY_H */ diff --git a/include/asm-ppc/namei.h b/include/asm-ppc/namei.h index 264d6624189c..9e0268b03b97 100644 --- a/include/asm-ppc/namei.h +++ b/include/asm-ppc/namei.h @@ -1,4 +1,4 @@ -/* $Id: namei.h,v 1.3 1997/08/29 15:52:22 jj Exp $ +/* $Id: namei.h,v 1.4 1998/10/28 08:13:33 jj Exp $ * linux/include/asm-ppc/namei.h * Adapted from linux/include/asm-alpha/namei.h * @@ -13,7 +13,7 @@ * Look at asm-sparc/namei.h for details. */ -#define __prefix_lookup_dentry(name, follow_link) \ +#define __prefix_lookup_dentry(name, lookup_flags) \ do {} while (0) #endif /* __PPC_NAMEI_H */ diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 1d8c0a800808..d0c0673b3dd2 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -618,8 +618,6 @@ extern void cache_push(__u32 addr, int length); extern int mm_end_of_chunk (unsigned long addr, int len); extern unsigned long iopa(unsigned long addr); extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); -#define VTOP(addr) (iopa((unsigned long)(addr))) -#define PTOV(addr) (mm_ptov((unsigned long)(addr))) /* Values for nocacheflag and cmode */ /* These are not used by the APUS kernel_map, but prevents diff --git a/include/asm-ppc/pmu.h b/include/asm-ppc/pmu.h index 672aeed2e30f..ee04ae2a8eda 100644 --- a/include/asm-ppc/pmu.h +++ b/include/asm-ppc/pmu.h @@ -54,6 +54,9 @@ void pmu_poll(void); void pmu_enable_backlight(int on); +void pmu_restart(void); +void pmu_shutdown(void); + /* * Stuff for putting the powerbook to sleep and waking it again. */ diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h index 7bce0c7a19dc..018da94fdee4 100644 --- a/include/asm-ppc/prom.h +++ b/include/asm-ppc/prom.h @@ -72,6 +72,7 @@ extern struct device_node *find_path_device(const char *path); extern struct device_node *find_compatible_devices(const char *type, const char *compat); extern struct device_node *find_phandle(phandle); +extern int device_is_compatible(struct device_node *device, const char* compat); extern unsigned char *get_property(struct device_node *node, const char *name, int *lenp); extern void print_properties(struct device_node *node); diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 033ffb96bb91..4fb817a8e190 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -13,8 +13,22 @@ #ifndef __ASSEMBLY__ -extern unsigned long cpu_present_map; extern int first_cpu_booted; +extern unsigned long smp_proc_in_lock[NR_CPUS]; + +extern void smp_message_pass(int target, int msg, unsigned long data, int wait); +extern void smp_store_cpu_info(int id); + +#define NO_PROC_ID 0xFF /* No processor magic marker */ +#define PROC_CHANGE_PENALTY 2000 + +/* 1 to 1 mapping on PPC -- Cort */ +#define cpu_logical_map(cpu) (cpu) +extern int cpu_number_map[NR_CPUS]; +extern volatile unsigned long cpu_callin_map[NR_CPUS]; + +#define hard_smp_processor_id() (0) +#define smp_processor_id() (current->processor) /* per processor PPC parameters we need. */ struct cpuinfo_PPC { @@ -33,40 +47,13 @@ struct klock_info_struct { }; extern struct klock_info_struct klock_info; - #define KLOCK_HELD 0xffffffff #define KLOCK_CLEAR 0x0 -#define PROC_CHANGE_PENALTY 20 - -extern __volatile__ int cpu_number_map[NR_CPUS]; -extern __volatile__ int __cpu_logical_map[NR_CPUS]; -extern unsigned long smp_proc_in_lock[NR_CPUS]; - -extern __inline__ int cpu_logical_map(int cpu) -{ - return __cpu_logical_map[cpu]; -} - -extern __inline__ int hard_smp_processor_id(void) -{ - int cpuid = 0; - /* assume cpu # 0 for now */ - return cpuid; -} - -#define smp_processor_id() (current->processor) - -extern void smp_message_pass(int target, int msg, unsigned long data, int wait); - #endif /* __ASSEMBLY__ */ #else /* !(__SMP__) */ #endif /* !(__SMP__) */ -#define NO_PROC_ID 0xFF /* No processor magic marker */ - -extern void smp_store_cpu_info(int id); - #endif /* !(_PPC_SMP_H) */ diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h index e2b36e3ecc87..5e8c3910e496 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-ppc/unistd.h @@ -5,7 +5,6 @@ * This file contains the system call numbers. */ -#define __NR_setup 0 /* used only by init, to get system going */ #define __NR_exit 1 #define __NR_fork 2 #define __NR_read 3 @@ -57,7 +56,7 @@ #define __NR_geteuid 49 #define __NR_getegid 50 #define __NR_acct 51 -#define __NR_phys 52 +#define __NR_umount2 52 #define __NR_lock 53 #define __NR_ioctl 54 #define __NR_fcntl 55 @@ -195,7 +194,6 @@ #define __NR_getpmsg 187 /* some people actually want streams */ #define __NR_putpmsg 188 /* some people actually want streams */ - #define __NR(n) #n @@ -394,7 +392,6 @@ static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long fl #define __NR__exit __NR_exit static inline _syscall0(int,idle) static inline _syscall0(int,pause) -static inline _syscall1(int,setup,int,magic) static inline _syscall0(int,sync) static inline _syscall0(pid_t,setsid) static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) diff --git a/include/asm-ppc/vga.h b/include/asm-ppc/vga.h index d82388831ca7..1ab739772e6b 100644 --- a/include/asm-ppc/vga.h +++ b/include/asm-ppc/vga.h @@ -21,8 +21,11 @@ extern inline u16 scr_readw(u16 *addr) return ld_le16(addr); } -#define VGA_MAP_MEM(x) (x + _ISA_MEM_BASE) +#define VT_BUF_HAVE_MEMCPYF +#define scr_memcpyw_from memcpy +#define scr_memcpyw_to memcpy +#define VGA_MAP_MEM(x) (x + _ISA_MEM_BASE) #define vga_readb(x) (*(x)) #define vga_writeb(x,y) (*(y) = (x)) diff --git a/net/802/fddi.c b/net/802/fddi.c index f544da731087..afe14c384f93 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c @@ -25,6 +25,7 @@ * Alan Cox : New arp/rebuild header */ +#include #include #include #include diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 780ed307f336..2e191a54102e 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -163,8 +163,6 @@ static struct neigh_ops arp_direct_ops = dev_queue_xmit }; -#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) || \ - defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) struct neigh_ops arp_broken_ops = { AF_INET, @@ -176,7 +174,6 @@ struct neigh_ops arp_broken_ops = dev_queue_xmit, dev_queue_xmit, }; -#endif struct neigh_table arp_tbl = { diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index 678098884a29..9aa0c3485418 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -19,6 +19,7 @@ * Dec 13, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE) *****************************************************************************/ +#include #include /* offsetof(), etc. */ #include /* return codes */ #include