diff options
Diffstat (limited to 'arch/m68k/mac')
-rw-r--r-- | arch/m68k/mac/config.c | 49 | ||||
-rw-r--r-- | arch/m68k/mac/debug.c | 156 | ||||
-rw-r--r-- | arch/m68k/mac/macboing.c | 357 | ||||
-rw-r--r-- | arch/m68k/mac/macints.c | 203 | ||||
-rw-r--r-- | arch/m68k/mac/mackeyb.c | 75 | ||||
-rw-r--r-- | arch/m68k/mac/via6522.c | 23 |
6 files changed, 530 insertions, 333 deletions
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index f410182e0..8e902d0bd 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -55,9 +55,6 @@ extern char m68k_command_line[CL_SIZE]; void *mac_env; /* Loaded by the boot asm */ -/* The logical video addr. determined by head.S - testing */ -extern unsigned long mac_videobase; - /* The phys. video addr. - might be bogus on some machines */ unsigned long mac_orig_videoaddr; @@ -65,7 +62,6 @@ unsigned long mac_orig_videoaddr; extern int mac_keyb_init(void); extern int mac_kbdrate(struct kbd_repeat *k); extern void mac_kbd_leds(unsigned int leds); -extern void mac_kbd_reset_setup(char*, int); /* Mac specific irq functions */ extern void mac_init_IRQ (void); @@ -100,17 +96,15 @@ extern void mac_debug_init(void); extern void mac_debugging_long(int, long); #ifdef CONFIG_MAGIC_SYSRQ - -/* XXX FIXME: Atari scancodes still */ static char mac_sysrq_xlate[128] = - "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ - "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ - "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ - "bnm,./\000\000\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ - "\206\207\210\211\212\000\000\000\000\000-\000\000\000+\000"/* 0x40 - 0x4f */ - "\000\000\000\177\000\000\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ - "\000\000\000()/*789456123" /* 0x60 - 0x6f */ - "0.\r\000\000\000\000\000\000\000\000\000\000\000\000\000"; /* 0x70 - 0x7f */ + "\000sdfghzxcv\000bqwer" /* 0x00 - 0x0f */ + "yt123465=97-80)o" /* 0x10 - 0x1f */ + "u(ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */ + "\t `\000\033\000\000\000\000\000\000\000\000\000\000\000" /* 0x30 - 0x3f */ + "\000.\000*\000+\000\000\000\000\000/\r\000-\000" /* 0x40 - 0x4f */ + "\000\00001234567a89\000\000\000" /* 0x50 - 0x5f */ + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" /* 0x60 - 0x6f */ + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"; /* 0x70 - 0x7f */ #endif extern void (*kd_mksound)(unsigned int, unsigned int); @@ -243,9 +237,7 @@ __initfunc(int mac_parse_bootinfo(const struct bi_record *record)) mac_bi_data.id = *data; break; case BI_MAC_VADDR: - /* save booter supplied videobase; use the one mapped in head.S! */ - mac_orig_videoaddr = *data; - mac_bi_data.videoaddr = mac_videobase; + mac_bi_data.videoaddr = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK); break; case BI_MAC_VDEPTH: mac_bi_data.videodepth = *data; @@ -309,7 +301,6 @@ __initfunc(void config_mac(void)) mach_keyb_init = mac_keyb_init; mach_kbdrate = mac_kbdrate; mach_kbd_leds = mac_kbd_leds; - kbd_reset_setup = mac_kbd_reset_setup; mach_init_IRQ = mac_init_IRQ; mach_request_irq = mac_request_irq; mach_free_irq = mac_free_irq; @@ -336,7 +327,7 @@ __initfunc(void config_mac(void)) #endif kd_mksound = mac_mksound; #ifdef CONFIG_MAGIC_SYSRQ - mach_sysrq_key = 98; /* HELP */ + mach_sysrq_key = 114; /* HELP */ mach_sysrq_shift_state = 8; /* Alt */ mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */ mach_sysrq_xlate = mac_sysrq_xlate; @@ -399,10 +390,10 @@ static struct mac_model mac_data_table[]= * */ - { MAC_MODEL_II, "II", MAC_ADB_II, MAC_VIA_II, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_NUBUS}, - { MAC_MODEL_IIX, "IIx", MAC_ADB_II, MAC_VIA_II, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_NUBUS}, - { MAC_MODEL_IICX, "IIcx", MAC_ADB_II, MAC_VIA_II, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_NUBUS}, - { MAC_MODEL_SE30, "SE/30", MAC_ADB_II, MAC_VIA_II, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_NUBUS}, + { MAC_MODEL_II, "II", MAC_ADB_II, MAC_VIA_II, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_IIX, "IIx", MAC_ADB_II, MAC_VIA_II, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_IICX, "IIcx", MAC_ADB_II, MAC_VIA_II, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_SE30, "SE/30", MAC_ADB_II, MAC_VIA_II, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, /* * Weirdified MacII hardware - all subtley different. Gee thanks @@ -425,7 +416,7 @@ static struct mac_model mac_data_table[]= */ { MAC_MODEL_CLII, "Classic II", MAC_ADB_IISI, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, - { MAC_MODEL_CCL, "Color Classic", MAC_ADB_IISI, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_CCL, "Color Classic", MAC_ADB_CUDA, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, /* * Some Mac LC machines. Basically the same as the IIci, ADB like IIsi @@ -461,11 +452,11 @@ static struct mac_model mac_data_table[]= * Performa - more LC type machines */ - { MAC_MODEL_P460, "Performa 460", MAC_ADB_IISI, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_P460, "Performa 460", MAC_ADB_IISI, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P475, "Performa 475", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P475F, "Performa 475", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P520, "Performa 520", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, - { MAC_MODEL_P550, "Performa 550", MAC_ADB_CUDA, MAC_VIA_IIci, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_P550, "Performa 550", MAC_ADB_CUDA, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P575, "Performa 575", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P588, "Performa 588", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_TV, "TV", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, @@ -477,8 +468,8 @@ static struct mac_model mac_data_table[]= * Centris - just guessing again; maybe like Quadra */ - { MAC_MODEL_C610, "Centris 610", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, - { MAC_MODEL_C650, "Centris 650", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_C610, "Centris 610", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS}, + { MAC_MODEL_C650, "Centris 650", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS}, { MAC_MODEL_C660, "Centris 660AV", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA3, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, /* @@ -551,7 +542,7 @@ void mac_identify(void) m++; } if(m->ident==-1) - mac_boom(5); + panic("mac model config data corrupt!\n"); } /* diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c index 62a8a6187..5aa7ce6cf 100644 --- a/arch/m68k/mac/debug.c +++ b/arch/m68k/mac/debug.c @@ -36,7 +36,10 @@ extern unsigned long mac_videobase; extern unsigned long mac_videodepth; extern unsigned long mac_rowbytes; -#define DEBUG_SCREEN +extern void mac_serial_print(char *); + +#define DEBUG_HEADS +#undef DEBUG_SCREEN #define DEBUG_SERIAL /* @@ -129,121 +132,6 @@ void mac_debugging_long(int pos, long addr) #endif } -/* - * Penguin - used by head.S console; obsolete - */ -char that_penguin[]={ -#include "that_penguin.h" -}; - -#ifdef DEBUG_SCREEN -/* - * B/W version of penguin, unfinished - any takers?? - */ -static char bw_penguin[]={ -#include "bw_penguin.h" -}; -#endif - -void mac_debugging_penguin(int peng) -{ -#ifdef DEBUG_SCREEN - unsigned char *pengoffset; - unsigned char *pptr; - unsigned char *bwpdptr=bw_penguin; - int i; -#endif - -#ifdef DEBUG_SERIAL - printk("Penguin: #%d !\n", peng); -#endif - -#ifdef DEBUG_SCREEN - if (!MACH_IS_MAC) - return; - - if (mac_videodepth ==1) - pengoffset=(unsigned char *)(mac_videobase+80*mac_rowbytes) - +5*peng; - else - pengoffset=(unsigned char *)(mac_videobase+80*mac_rowbytes) - +20*peng; - - pptr=pengoffset; - - for(i=0;i<36;i++) - { - memcpy(pptr,bwpdptr,4); - bwpdptr+=4; - pptr+=mac_rowbytes; - } -#endif -} - -#ifdef DEBUG_SCREEN -/* - * B/W version of flaming Mac, unfinished (see above). - */ -static char bw_kaboom_map[]={ -#include "bw_mac.h" -}; -#endif - -#ifdef DEBUG_SCREEN -static void mac_boom_boom(void) -{ - static unsigned char *boomoffset=NULL; - unsigned char *pptr; - unsigned char *bwpdptr=bw_kaboom_map; - int i; - -#ifdef DEBUG_SERIAL - printk("BOOM !\n"); -#endif - - if (!MACH_IS_MAC) - return; - - if(!boomoffset) - if (mac_videodepth == 1) { - boomoffset=(unsigned char *)(mac_videobase+160*mac_rowbytes); - } else { - boomoffset=(unsigned char *)(mac_videobase+256*mac_rowbytes); - } - else - if (mac_videodepth == 1) - boomoffset+=5; - else - boomoffset+=32; - - pptr=boomoffset; - - for(i=0;i<36;i++) - { - memcpy(pptr,bwpdptr,4); - bwpdptr+=4; - pptr+=mac_rowbytes; - } -} -#endif - -void mac_boom(int booms) -{ -#ifdef DEBUG_SCREEN - int i; -#endif - - if (!MACH_IS_MAC) - return; - -#ifdef DEBUG_SCREEN - for(i=0;i<booms;i++) - mac_boom_boom(); - while(1); -#endif -} - - #ifdef DEBUG_SERIAL /* * TODO: serial debug code @@ -284,6 +172,29 @@ static struct console mac_console_driver = { NULL }; +/* + * Crude hack to get console output to the screen before the framebuffer + * is initialized (happens a lot later in 2.1!). + * We just use the console routines declared in head.S, this will interfere + * with regular framebuffer console output and should be used exclusively + * to debug kernel problems manifesting before framebuffer init (aka WSOD) + * + * To keep this hack from interfering with the regular console driver, either + * deregister this driver before/on framebuffer console init, or silence this + * function after the fbcon driver is running (will lose console messages!?). + * To debug real early bugs, need to write a 'mac_register_console_hack()' + * that is called from start_kernel() before setup_arch() and just registers + * this driver if Mac. + */ + +void mac_debug_console_write (struct console *co, const char *str, + unsigned int count) +{ + mac_serial_print(str); +} + + + /* Mac: loops_per_sec min. 1900000 ^= .5 us; MFPDELAY was 0.6 us*/ #define uSEC 1 @@ -486,19 +397,30 @@ __initfunc(void mac_debug_init(void)) /* Mac modem port */ mac_init_scc_port( B9600|CS8, 0 ); mac_console_driver.write = mac_scca_console_write; +#ifdef CONFIG_SERIAL_CONSOLE mac_console_driver.wait_key = mac_scca_console_wait_key; +#endif scc_port = 0; } else if (!strcmp( m68k_debug_device, "ser2" )) { /* Mac printer port */ mac_init_scc_port( B9600|CS8, 1 ); mac_console_driver.write = mac_sccb_console_write; +#ifdef CONFIG_SERIAL_CONSOLE mac_console_driver.wait_key = mac_sccb_console_wait_key; +#endif scc_port = 1; } +#endif +#ifdef DEBUG_HEADS + if ( !strcmp( m68k_debug_device, "scn" ) + || !strcmp( m68k_debug_device, "con" )) { + /* display, using head.S console routines */ + mac_console_driver.write = mac_debug_console_write; + } +#endif if (mac_console_driver.write) register_console(&mac_console_driver); -#endif } /* diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c index 95078a384..1731c929c 100644 --- a/arch/m68k/mac/macboing.c +++ b/arch/m68k/mac/macboing.c @@ -1,6 +1,12 @@ /* * Mac bong noise generator. Note - we ought to put a boingy noise * here 8) + * + * ---------------------------------------------------------------------- + * 16.11.98: + * rewrote some functions, added support for Enhanced ASC (Quadras) + * after the NetBSD asc.c console bell patch by Colin Wood/Frederick Bruck + * Juergen Mellinger (juergen.mellinger@t-online.de) */ #include <linux/sched.h> @@ -9,124 +15,281 @@ #include <asm/macintosh.h> #include <asm/mac_asc.h> +static int mac_asc_inited = 0; +/* + * dumb triangular wave table + */ +static __u8 mac_asc_wave_tab[ 0x800 ]; + +/* + * Alan's original sine table; needs interpolating to 0x800 + * (hint: interpolate or hardwire [0 -> Pi/2[, it's symmetric) + */ static const signed char sine_data[] = { 0, 39, 75, 103, 121, 127, 121, 103, 75, 39, 0, -39, -75, -103, -121, -127, -121, -103, -75, -39 }; -#define DATA_SIZE (sizeof(sine_data)/sizeof(sine_data[0])) -static void nosound( unsigned long ignored ); -static struct timer_list sound_timer = { NULL, NULL, 0, 0, nosound }; +/* + * where the ASC hides ... + */ +static volatile __u8* mac_asc_regs = ( void* )0x50F14000; -static volatile unsigned char *asc_base=(void *)0x50F14000; +/* + * sample rate; is this a good default value? + */ +static unsigned long mac_asc_samplespersec = 11050; +static int mac_bell_duration = 0; +static unsigned long mac_bell_phase; /* 0..2*Pi -> 0..0x800 (wavetable size) */ +static unsigned long mac_bell_phasepersample; + +/* + * some function protos + */ +static void mac_init_asc( void ); +static void mac_nosound( unsigned long ); +static void mac_quadra_start_bell( unsigned int, unsigned int, unsigned int ); +static void mac_quadra_ring_bell( unsigned long ); +static void mac_av_start_bell( unsigned int, unsigned int, unsigned int ); +static void ( *mac_special_bell )( unsigned int, unsigned int, unsigned int ) = NULL; +/* + * our timer to start/continue/stop the bell + */ +static struct timer_list mac_sound_timer = { NULL, NULL, 0, 0, mac_nosound }; -void mac_mksound( unsigned int hz, unsigned int ticks ) +/* + * Sort of initialize the sound chip (called from mac_mksound on the first + * beep). + */ +static void mac_init_asc( void ) { - static int inited = 0; - unsigned long flags; - int samples=512; + int i; - if (macintosh_config->ident == MAC_MODEL_C660 - || macintosh_config->ident == MAC_MODEL_Q840) + /* + * do some machine specific initialization + * BTW: + * the NetBSD Quadra patch identifies the Enhanced Apple Sound Chip via + * mac_asc_regs[ 0x800 ] & 0xF0 != 0 + * this makes no sense here, because we have to set the default sample + * rate anyway if we want correct frequencies + */ + switch ( macintosh_config->ident ) { - /* - * The Quadra 660AV and 840AV use the "Singer" custom ASIC for sound I/O. - * It appears to be similar to the "AWACS" custom ASIC in the Power Mac - * [678]100. Because Singer and AWACS may have a similar hardware - * interface, this would imply that the code in drivers/sound/dmasound.c - * for AWACS could be used as a basis for Singer support. All we have to - * do is figure out how to do DMA on the 660AV/840AV through the PSC and - * figure out where the Singer hardware sits in memory. (I'd look in the - * vicinity of the AWACS location in a Power Mac [678]100 first, or the - * current location of the Apple Sound Chip--ASC--in other Macs.) The - * Power Mac [678]100 info can be found in MkLinux Mach kernel sources. - * - * Quoted from Apple's Tech Info Library, article number 16405: - * "Among desktop Macintosh computers, only the 660AV, 840AV, and Power - * Macintosh models have 16-bit audio input and output capability - * because of the AT&T DSP3210 hardware circuitry and the 16-bit Singer - * codec circuitry in the AVs. The Audio Waveform Amplifier and - * Converter (AWAC) chip in the Power Macintosh performs the same - * 16-bit I/O functionality. The PowerBook 500 series computers - * support 16-bit stereo output, but only mono input." - * - * http://til.info.apple.com/techinfo.nsf/artnum/n16405 - * - * --David Kilzer - */ + case MAC_MODEL_IIFX: + /* + * The IIfx is always special ... + */ + mac_asc_regs = ( void* )0x50010000; + break; + /* + * not sure about how correct this list is + * machines with the EASC enhanced apple sound chip + */ + case MAC_MODEL_Q630: + case MAC_MODEL_P475: + mac_special_bell = mac_quadra_start_bell; + mac_asc_samplespersec = 22150; + break; + case MAC_MODEL_Q650: + case MAC_MODEL_Q700: + case MAC_MODEL_Q800: + case MAC_MODEL_Q900: + case MAC_MODEL_Q950: + /* + * Currently not implemented! + */ + /* + * The Quadra 660AV and 840AV use the "Singer" custom ASIC for sound I/O. + * It appears to be similar to the "AWACS" custom ASIC in the Power Mac + * [678]100. Because Singer and AWACS may have a similar hardware + * interface, this would imply that the code in drivers/sound/dmasound.c + * for AWACS could be used as a basis for Singer support. All we have to + * do is figure out how to do DMA on the 660AV/840AV through the PSC and + * figure out where the Singer hardware sits in memory. (I'd look in the + * vicinity of the AWACS location in a Power Mac [678]100 first, or the + * current location of the Apple Sound Chip--ASC--in other Macs.) The + * Power Mac [678]100 info can be found in MkLinux Mach kernel sources. + * + * Quoted from Apple's Tech Info Library, article number 16405: + * "Among desktop Macintosh computers, only the 660AV, 840AV, and Power + * Macintosh models have 16-bit audio input and output capability + * because of the AT&T DSP3210 hardware circuitry and the 16-bit Singer + * codec circuitry in the AVs. The Audio Waveform Amplifier and + * Converter (AWAC) chip in the Power Macintosh performs the same + * 16-bit I/O functionality. The PowerBook 500 series computers + * support 16-bit stereo output, but only mono input." + * + * http://til.info.apple.com/techinfo.nsf/artnum/n16405 + * + * --David Kilzer + */ + mac_special_bell = mac_av_start_bell; + break; + } + + /* + * init the wave table with a simple triangular wave + * A sine wave would sure be nicer here ... + */ + for ( i = 0; i < 0x400; i++ ) + { + mac_asc_wave_tab[ i ] = i / 4; + mac_asc_wave_tab[ i + 0x400 ] = 0xFF - i / 4; + } + mac_asc_inited = 1; +} +/* + * Called to make noise; current single entry to the boing driver. + * Does the job for simple ASC, calls other routines else. + * XXX Fixme: + * Should be split into asc_mksound, easc_mksound, av_mksound and + * function pointer set in mac_init_asc which would be called at + * init time. + * _This_ is rather ugly ... + */ +void mac_mksound( unsigned int freq, unsigned int length ) +{ + __u32 cfreq = ( freq << 5 ) / 468; + __u32 flags; + int i; + + if ( !mac_asc_inited ) + mac_init_asc(); + + if ( mac_special_bell ) + { + mac_special_bell( freq, length, 128 ); return; } - - if(!inited) + + if ( freq < 20 || freq > 20000 || length == 0 ) { - int i=0; - int j=0; - int k=0; - int l=0; - - /* - * The IIfx strikes again! - */ - - if(macintosh_config->ident==MAC_MODEL_IIFX) - asc_base=(void *)0x50010000; - - for(i=0;i<samples;i++) - { - asc_base[i]=sine_data[j]; - asc_base[i+512]=sine_data[j]; - asc_base[i+1024]=sine_data[j]; - asc_base[i+1536]=sine_data[j]; - j++; - if(j==DATA_SIZE) - j=0; - if(i&1) - k++; - if(k==DATA_SIZE) - k=0; - if((i&3)==3) - l++; - if(l==DATA_SIZE) - l=0; - } - inited=1; + mac_nosound( 0 ); + return; } - save_flags(flags); + + save_flags( flags ); cli(); - del_timer( &sound_timer ); - if (hz > 20 && hz < 32767) { - int i; - u_long asc_pulses=((hz<<5)*samples)/468; - for(i=0;i<4;i++) + del_timer( &mac_sound_timer ); + + for ( i = 0; i < 0x800; i++ ) + mac_asc_regs[ i ] = 0; + for ( i = 0; i < 0x800; i++ ) + mac_asc_regs[ i ] = mac_asc_wave_tab[ i ]; + + for ( i = 0; i < 8; i++ ) + *( __u32* )( ( __u32 )mac_asc_regs + ASC_CONTROL + 0x814 + 8 * i ) = cfreq; + + mac_asc_regs[ 0x807 ] = 0; + mac_asc_regs[ ASC_VOLUME ] = 128; + mac_asc_regs[ 0x805 ] = 0; + mac_asc_regs[ 0x80F ] = 0; + mac_asc_regs[ ASC_MODE ] = ASC_MODE_SAMPLE; + mac_asc_regs[ ASC_ENABLE ] = ASC_ENABLE_SAMPLE; + + mac_sound_timer.expires = jiffies + length; + add_timer( &mac_sound_timer ); + + restore_flags( flags ); +} + +/* + * regular ASC: stop whining .. + */ +static void mac_nosound( unsigned long ignored ) +{ + mac_asc_regs[ ASC_ENABLE ] = 0; +} + +/* + * EASC entry; init EASC, don't load wavetable, schedule 'start whining'. + */ +static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume ) +{ + __u32 flags; + + /* if the bell is already ringing, ring longer */ + if ( mac_bell_duration > 0 ) + { + mac_bell_duration += length; + return; + } + + mac_bell_duration = length; + mac_bell_phase = 0; + mac_bell_phasepersample = ( freq * sizeof( mac_asc_wave_tab ) ) / mac_asc_samplespersec; + /* this is reasonably big for small frequencies */ + + save_flags( flags ); + cli(); + + /* set the volume */ + mac_asc_regs[ 0x806 ] = volume; + + /* set up the ASC registers */ + if ( mac_asc_regs[ 0x801 ] != 1 ) + { + /* select mono mode */ + mac_asc_regs[ 0x807 ] = 0; + /* select sampled sound mode */ + mac_asc_regs[ 0x802 ] = 0; + /* ??? */ + mac_asc_regs[ 0x801 ] = 1; + mac_asc_regs[ 0x803 ] |= 0x80; + mac_asc_regs[ 0x803 ] &= 0x7F; + } + + mac_sound_timer.function = mac_quadra_ring_bell; + mac_sound_timer.expires = jiffies + 1; + add_timer( &mac_sound_timer ); + + restore_flags( flags ); +} + +/* + * EASC 'start/continue whining'; I'm not sure why the above function didn't + * already load the wave table, or at least call this one... + * This piece keeps reloading the wave table until done. + */ +static void mac_quadra_ring_bell( unsigned long ignored ) +{ + int i, count = mac_asc_samplespersec / HZ; + __u32 flags; + + /* + * we neither want a sound buffer overflow nor underflow, so we need to match + * the number of samples per timer interrupt as exactly as possible. + * using the asc interrupt will give better results in the future + * ...and the possibility to use a real sample (a boingy noise, maybe...) + */ + + save_flags( flags ); + cli(); + + del_timer( &mac_sound_timer ); + + if ( mac_bell_duration-- > 0 ) + { + for ( i = 0; i < count; i++ ) { - asc_base[ASC_FREQ(i,0)]=0x00; - asc_base[ASC_FREQ(i,1)]=20; - asc_base[ASC_FREQ(i,2)]=0x00; - asc_base[ASC_FREQ(i,3)]=20; - asc_base[ASC_FREQ(i,4)]=(asc_pulses>>24)&0xFF; - asc_base[ASC_FREQ(i,5)]=(asc_pulses>>16)&0xFF; - asc_base[ASC_FREQ(i,6)]=(asc_pulses>>8)&0xFF; - asc_base[ASC_FREQ(i,7)]=(asc_pulses>>0)&0xFF; + mac_bell_phase += mac_bell_phasepersample; + mac_asc_regs[ 0 ] = mac_asc_wave_tab[ mac_bell_phase & ( sizeof( mac_asc_wave_tab ) - 1 ) ]; } - asc_base[ASC_CHAN]=0x03; - asc_base[ASC_VOLUME]=128; - asc_base[ASC_MODE]=ASC_MODE_SAMPLE; - asc_base[ASC_ENABLE]=ASC_ENABLE_SAMPLE; - if (ticks) { - sound_timer.expires = jiffies + ticks; - add_timer( &sound_timer ); - } - } else { - nosound( 0 ); + mac_sound_timer.expires = jiffies + 1; + add_timer( &mac_sound_timer ); } - restore_flags(flags); + else + mac_asc_regs[ 0x801 ] = 0; + + restore_flags( flags ); } - -static void nosound( unsigned long ignored ) +/* + * AV code - please fill in. + */ +static void mac_av_start_bell( unsigned int freq, unsigned int length, unsigned int volume ) { - asc_base[ASC_ENABLE]=0; -} +} diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index b703cb275..87e6692d4 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -163,7 +163,14 @@ static unsigned long nubus_irqs[8]; static unsigned long *mac_irqs[8]; /* - * VIA2 / RBV register base pointers + * Some special nutcases ... + */ + +static unsigned long mac_ide_irqs = 0; +static unsigned long nubus_stuck_events = 0; + +/* + * VIA/RBV/OSS/PSC register base pointers */ volatile unsigned char *via2_regp=(volatile unsigned char *)VIA2_BAS; @@ -217,9 +224,13 @@ void mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs); static void via_do_nubus(int slot, void *via, struct pt_regs *regs); /* #define DEBUG_MACINTS */ -/* #define DEBUG_NUBUS_INT */ + +#define DEBUG_SPURIOUS +#define DEBUG_NUBUS_SPURIOUS +#define DEBUG_NUBUS_INT + /* #define DEBUG_VIA */ -/* #define DEBUG_VIA_NUBUS */ +#define DEBUG_VIA_NUBUS void mac_init_IRQ(void) { @@ -247,7 +258,7 @@ void mac_init_IRQ(void) /* yes, this is messy - the IIfx deserves a class of his own */ if (macintosh_config->ident == MAC_MODEL_IIFX) { - /* no real VIA2, the OSS seems _very_different */ + /* no real VIA2, the OSS seems _very_ different */ via2_is_oss = 1; /* IIfx has OSS, at a different base address than RBV */ rbv_regp = (unsigned char *) OSS_BAS; @@ -351,6 +362,12 @@ void mac_init_IRQ(void) mac_irqs[7] = &nubus_irqs[0]; /* + * Nubus Macs: turn off the Nubus dispatch interrupt for now + */ + + mac_turnoff_irq(IRQ_MAC_NUBUS); + + /* * AV Macs: shutup the PSC ints */ if (macintosh_config->ident == MAC_MODEL_C660 @@ -430,8 +447,10 @@ int mac_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_re return 0; } - /* add similar hack for Nubus pseudo-irq here - hide nubus_request_irq */ - + /* + * code below: only for VIA irqs currently + * add similar hack for Nubus pseudo-irq here - hide nubus_request_irq + */ via = (volatile unsigned char *) via_table[srcidx]; if (!via) return -EINVAL; @@ -459,7 +478,7 @@ int mac_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_re if (irq == IRQ_IDX(IRQ_MAC_SCSI)) { /* * Set vPCR for SCSI interrupts. (what about RBV here?) - * 980429 MS: RBV is ok, OSS seems to be differentt + * 980429 MS: RBV is ok, OSS seems to be different */ if (!via2_is_oss) if (macintosh_config->scsi_type == MAC_SCSI_OLD) { @@ -602,7 +621,10 @@ void mac_disable_irq (unsigned int irq) /* * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not - * "stored". This is done with the VIA interrupt enable register + * "stored". This is done with the VIA interrupt enable register on VIAs. + * + * Note: Using these functions on non-VIA/OSS/PSC ints will panic, or at least + * have undesired side effects. */ void mac_turnon_irq( unsigned int irq ) @@ -615,14 +637,14 @@ void mac_turnon_irq( unsigned int irq ) if (!via) return; - if (srcidx == SRC_VIA2 && via2_is_rbv) + if (srcidx == SRC_VIA2 && via2_is_rbv) /* RBV as VIA2 */ via_write(via, rIER, via_read(via, rIER)|0x80|(1<<(irqidx))); - else if (srcidx == SRC_VIA2 && via2_is_oss) + else if (srcidx == SRC_VIA2 && via2_is_oss) /* OSS */ via_write(oss_regp, oss_map[irqidx]+8, 2); - else if (srcidx > SRC_VIA2) + else if (srcidx > SRC_VIA2) /* hope AVs have VIA2 */ via_write(via, (0x104 + 0x10*srcidx), via_read(via, (0x104 + 0x10*srcidx))|0x80|(1<<(irqidx))); - else + else /* VIA1+2 */ via_write(via, vIER, via_read(via, vIER)|0x80|(1<<(irqidx))); } @@ -637,9 +659,9 @@ void mac_turnoff_irq( unsigned int irq ) if (!via) return; - if (srcidx == SRC_VIA2 && via2_is_rbv) + if (srcidx == SRC_VIA2 && via2_is_rbv) /* RBV as VIA2 */ via_write(via, rIER, (via_read(via, rIER)&(1<<irqidx))); - else if (srcidx == SRC_VIA2 && via2_is_oss) + else if (srcidx == SRC_VIA2 && via2_is_oss) /* OSS */ via_write(oss_regp, oss_map[irqidx]+8, 0); /* * VIA2 is fixed. The stuff above VIA2 is for later @@ -648,7 +670,7 @@ void mac_turnoff_irq( unsigned int irq ) else if (srcidx > SRC_VIA2) via_write(via, (0x104 + 0x10*srcidx), via_read(via, (0x104 + 0x10*srcidx))|(1<<(irqidx))); - else + else /* VIA1+2 */ via_write(via, vIER, (via_read(via, vIER)&(1<<irqidx))); } @@ -694,12 +716,18 @@ int mac_irq_pending( unsigned int irq ) return (pending); } +/* + * for /proc/interrupts: log interrupt stats broken down by + * autovector int first, then by actual interrupt source. + */ + int mac_get_irq_list (char *buf) { int i, len = 0; int srcidx, irqidx; for (i = VIA1_SOURCE_BASE; i < NUM_MAC_SOURCES+8; ++i) { + /* XXX fixme: IRQ_SRC_MASK should cover VIA1 - Nubus */ srcidx = ((i & IRQ_SRC_MASK)>>3) - 1; irqidx = (i & IRQ_IDX_MASK); @@ -764,6 +792,32 @@ int mac_get_irq_list (char *buf) } if (num_spurious) len += sprintf(buf+len, "spurio.: %10u\n", num_spurious); + + /* + * XXX Fixme: Nubus sources are never logged above ... + */ + + len += sprintf(buf+len, "Nubus interrupts:\n"); + + for (i = 0; i < 7; i++) { + if (nubus_handler[i].handler == nubus_wtf) + continue; + len += sprintf(buf+len, "nubus %01X: %10lu ", + i+9, + nubus_irqs[i]); + len += sprintf(buf+len, "%s\n", + nubus_param[i].devname); + + } + len += sprintf(buf+len, "nubus spurious ints: %10lu\n", + nubus_irqs[7]); + len += sprintf(buf+len, "nubus stuck events : %10lu\n", + nubus_stuck_events); +#ifdef CONFIG_BLK_DEV_IDE + len += sprintf(buf+len, "nubus/IDE interrupt: %10lu\n", + mac_ide_irqs); +#endif + return len; } @@ -784,8 +838,9 @@ void via_scsi_clear(void) void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs) { -#ifdef DEBUG_VIA - printk("Unexpected IRQ %d\n", irq); +#ifdef DEBUG_SPURIOUS + if (console_loglevel > 6) + printk("Unexpected IRQ %d on device %p\n", irq, dev_id); #endif } @@ -861,6 +916,18 @@ void mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp) } /* + * Unexpected via interrupt + */ + +void via_wtf(int slot, void *via, struct pt_regs *regs) +{ +#ifdef DEBUG_SPURIOUS + if (console_loglevel > 6) + printk("Unexpected nubus event %d on via %p\n",slot,via); +#endif +} + +/* * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's * via6522.c :-), disable/pending masks added. * The int *viaidx etc. is just to keep the prototype happy ... @@ -1115,17 +1182,6 @@ void rbv_irq(int irq, void *dev_id, struct pt_regs *regs) } /* - * Unexpected via interrupt - */ - -void via_wtf(int slot, void *via, struct pt_regs *regs) -{ -#ifdef DEBUG_VIA - printk("Unexpected event %d on via %p\n",slot,via); -#endif -} - -/* * Nubus / SCSI interrupts; OSS style * The OSS is even more different than the RBV. OSS appears to stand for * Obscenely Screwed Silicon ... @@ -1264,8 +1320,9 @@ void oss_irq(int irq, void *dev_id, struct pt_regs *regs) void nubus_wtf(int slot, void *via, struct pt_regs *regs) { -#ifdef DEBUG_VIA_NUBUS - printk("Unexpected interrupt on nubus slot %d\n",slot); +#ifdef DEBUG_NUBUS_SPURIOUS + if (console_loglevel > 6) + printk("Unexpected interrupt on nubus slot %d\n",slot); #endif } @@ -1279,9 +1336,10 @@ void mac_SCC_handler(int irq, void *dev_id, struct pt_regs *regs) int i; /* 1+2: compatibility with PSC ! */ for (i = 1; i < 3; i++) /* currently only these two used */ - if (scc_handler[i].handler != mac_default_handler) + if (scc_handler[i].handler != mac_default_handler) { (scc_handler[i].handler)(i, scc_handler[i].dev_id, regs); - + scc_irqs[i]++; + } } /* @@ -1310,7 +1368,7 @@ void psc_irq(int irq, void *dev_id, struct pt_regs *regs) if(events==0) { #ifdef DEBUG_VIA - printk("rbv_irq: nothing pending, flags %x mask %x!\n", + printk("psc_irq: nothing pending, flags %x mask %x!\n", via_read(via, pIFR), via_read(via,pIER)); #endif mac_irqs[srcidx][7]++; @@ -1319,7 +1377,7 @@ void psc_irq(int irq, void *dev_id, struct pt_regs *regs) #ifdef DEBUG_VIA /* - * limited verbosity for RBV interrupts (add more if needed) + * limited verbosity for PSC interrupts (add more if needed) */ if ( srcidx == 1 && events != 1<<3 && events != 1<<1 ) /* SCSI IRQ */ printk("psc_irq: irq %d srcidx+1 %d events %x !\n", irq, srcidx+1, events); @@ -1423,6 +1481,7 @@ int nubus_request_irq(int slot, void *dev_id, void (*handler)(int,void *,struct if (!nubus_active && !via2_is_oss) { request_irq(IRQ_MAC_NUBUS, via_do_nubus, IRQ_FLG_LOCK, "nubus dispatch", via_do_nubus); + mac_turnon_irq(IRQ_MAC_NUBUS); } nubus_active|=1<<slot; @@ -1472,6 +1531,7 @@ int nubus_free_irq(int slot) * IDE interrupt hook */ extern void (*mac_ide_intr_hook)(int, void *, struct pt_regs *); +extern int (*mac_ide_irq_p_hook)(void); #endif /* @@ -1479,13 +1539,13 @@ extern void (*mac_ide_intr_hook)(int, void *, struct pt_regs *); */ static void via_do_nubus(int slot, void *via, struct pt_regs *regs) { - unsigned char map; + unsigned char map, allints; int i; int ct=0; - -/* printk("nubus interrupt\n");*/ + int ide_pending = 0; /* lock the nubus interrupt */ + /* That's just 'clear Nubus IRQ bit in VIA2' BTW. Pretty obsolete ? */ if (via2_is_rbv) via_write(rbv_regp, rIFR, 0x82); else @@ -1493,36 +1553,69 @@ static void via_do_nubus(int slot, void *via, struct pt_regs *regs) #ifdef CONFIG_BLK_DEV_MAC_IDE /* IDE hack */ - if (mac_ide_intr_hook) + if (mac_ide_intr_hook) { /* 'slot' is lacking the machspec bit in 2.0 */ /* need to pass proper dev_id = hwgroup here */ mac_ide_intr_hook(IRQ_MAC_NUBUS, via, regs); + mac_ide_irqs++; + } #endif while(1) { if (via2_is_rbv) - map = ~via_read(rbv_regp, rBufA); + allints = ~via_read(rbv_regp, rBufA); else - map = ~via_read(via2_regp, vBufA); + allints = ~via_read(via2_regp, vBufA); - if( (map = (map&nubus_active)) ==0 ) { -#ifdef DEBUG_NUBUS_INT - printk("nubus_irq: nothing pending, map %x mask %x\n", - map, nubus_active); +#ifdef CONFIG_BLK_DEV_MAC_IDE + if (mac_ide_irq_p_hook) + ide_pending = mac_ide_irq_p_hook(); +#endif + + if ( (map = (allints&nubus_active)) == 0 +#ifdef CONFIG_BLK_DEV_MAC_IDE + && !ide_pending #endif - nubus_irqs[7]++; + ) + { + if (ct == 0) { +#ifdef DEBUG_VIA_NUBUS + if (console_loglevel > 5) + printk("nubus_irq: nothing pending, map %x mask %x active %x\n", + allints, nubus_active, map); +#endif + nubus_irqs[7]++; + } + /* clear it */ + if (allints) + if (via2_is_rbv) + via_write(rbv_regp, rIFR, 0x02); + else + via_write(via2_regp, vIFR, 0x02); break; } -#ifdef DEBUG_NUBUS_INT - printk("nubus_irq: map %x mask %x\n", map, nubus_active); + +#ifdef DEBUG_VIA_NUBUS + if (console_loglevel > 6) + printk("nubus_irq: map %x mask %x active %x\n", + allints, nubus_active, map); +#endif + +#ifdef CONFIG_BLK_DEV_MAC_IDE + if (mac_ide_intr_hook && ide_pending) { + mac_ide_intr_hook(IRQ_MAC_NUBUS, via, regs); + mac_ide_irqs++; + } #endif if(ct++>2) { -#ifdef DEBUG_NUBUS_INT - printk("nubus stuck events - %d/%d\n", map, nubus_active); -#endif + if (console_loglevel > 5) + printk("nubus stuck events - %x/%x/%x ide %x\n", + allints, nubus_active, map, ide_pending); + nubus_stuck_events++; + return; } @@ -1579,12 +1672,14 @@ static void oss_do_nubus(int slot, void *via, struct pt_regs *regs) printk("nubus_irq: map %x mask %x\n", map, nubus_active); #endif if( (map = (map&nubus_active)) ==0 ) { + if (ct == 0) { #ifdef CONFIG_BLK_DEV_MAC_IDE - if (!mac_ide_intr_hook) - printk("nubus_irq: nothing pending, map %x mask %x\n", - map, nubus_active); + if (!mac_ide_intr_hook) + printk("nubus_irq: nothing pending, map %x mask %x\n", + map, nubus_active); #endif - nubus_irqs[7]++; + nubus_irqs[7]++; + } break; } diff --git a/arch/m68k/mac/mackeyb.c b/arch/m68k/mac/mackeyb.c index 64cd5e1f8..5a6ae7c75 100644 --- a/arch/m68k/mac/mackeyb.c +++ b/arch/m68k/mac/mackeyb.c @@ -1,5 +1,12 @@ /* - * linux/arch/m68k/mac/mackeyb.c + * linux/arch/m68k/mac/mackeyb.c + * + * Keyboard driver for Macintosh computers. + * + * Adapted from drivers/macintosh/key_mac.c and arch/m68k/atari/akakeyb.c + * (see that file for its authors and contributors). + * + * Copyright (C) 1997 Michael Schmitz. * * 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 @@ -10,6 +17,7 @@ * misc. keyboard stuff (everything not in adb-bus.c or keyb_m68k.c) */ +#include <linux/config.h> #include <linux/types.h> #include <linux/mm.h> #include <linux/kd.h> @@ -59,8 +67,15 @@ extern void put_queue(int); static void mac_leds_done(struct adb_request *); static void keyboard_input(unsigned char *, int, struct pt_regs *); static void mouse_input(unsigned char *, int, struct pt_regs *); -/* Hook for mouse driver */ -void (*adb_mouse_interrupt_hook) (char *, int); + +#ifdef CONFIG_ADBMOUSE +/* XXX: Hook for mouse driver */ +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 + /* The mouse driver - for debugging */ extern void adb_mouse_interrupt(char *, int); /* end keyb */ @@ -275,9 +290,11 @@ input_keycode(int keycode, int repeat) kbd = kbd_table + fg_console; up_flag = (keycode & 0x80); keycode &= 0x7f; + if (!repeat) del_timer(&repeat_timer); +#ifdef CONFIG_ADBMOUSE /* * XXX: Add mouse button 2+3 fake codes here if mouse open. * As we only report up/down events, keep track of faked buttons. @@ -289,7 +306,8 @@ input_keycode(int keycode, int repeat) * (wanted: command and alt/option, or KP= and KP( ...) * Debug version; might be rewritten to be faster on normal keys. */ - if (adb_mouse_interrupt_hook || console_loglevel >= 8) { + if (adb_emulate_buttons + && (adb_mouse_interrupt_hook || console_loglevel >= 8)) { unsigned char button, button2, button3, fake_event; static unsigned char button2state=0, button3state=0; /* up */ /* faked ADB packet */ @@ -297,21 +315,20 @@ input_keycode(int keycode, int repeat) button = 0; fake_event = 0; - switch (keycode) { /* which 'button' ? */ - case 0x7c: /* R-option */ - button2 = (!up_flag); /* new state */ - if (button2 != button2state) /* change ? */ - button = 2; - button2state = button2; /* save state */ - fake_event = 2; - break; - case 0x7d: /* R-control */ - button3 = (!up_flag); /* new state */ - if (button3 != button3state) /* change ? */ - button = 3; - button3state = button3; /* save state */ - fake_event = 3; - break; + if (keycode == adb_button2_keycode) { /* which 'button' ? */ + /* R-option */ + button2 = (!up_flag); /* new state */ + if (button2 != button2state) /* change ? */ + button = 2; + button2state = button2; /* save state */ + fake_event = 2; + } else if (keycode == adb_button3_keycode) { + /* R-control */ + button3 = (!up_flag); /* new state */ + if (button3 != button3state) /* change ? */ + button = 3; + button3state = button3; /* save state */ + fake_event = 3; } #ifdef DEBUG_ADBMOUSE if (fake_event && console_loglevel >= 8) @@ -340,6 +357,7 @@ input_keycode(int keycode, int repeat) if (fake_event) return; } +#endif /* CONFIG_ADBMOUSE */ /* * Convert R-shift/control/option to L version. @@ -365,16 +383,18 @@ input_keycode(int keycode, int repeat) * transition into a key-down transition. * MSch: need to turn each caps-lock event into a down-up * double event (keyboard code assumes caps-lock is a toggle) + * 981127: fix LED behavior (kudos atong!) */ -#if 0 - if (keycode == 0x39 && up_flag && vc_kbd_led(kbd, VC_CAPSLOCK)) - up_flag = 0; -#else - if (keycode == 0x39) { + switch (keycode) { + case 0x39: handle_scancode(keycode); /* down */ up_flag = 0x80; /* see below ... */ + mark_bh(KEYBOARD_BH); + break; + case 0x47: + mark_bh(KEYBOARD_BH); + break; } -#endif } handle_scancode(keycode + up_flag); @@ -740,8 +760,3 @@ __initfunc(int mac_keyb_init(void)) return 0; } - -/* for "kbd-reset" cmdline param */ -__initfunc(void mac_kbd_reset_setup(char *str, int *ints)) -{ -} diff --git a/arch/m68k/mac/via6522.c b/arch/m68k/mac/via6522.c index 08ca49071..05e6f44e4 100644 --- a/arch/m68k/mac/via6522.c +++ b/arch/m68k/mac/via6522.c @@ -304,10 +304,11 @@ void mac_reset(void) unsigned long flags; unsigned long *reset_hook; - save_flags(flags); - cli(); - /* need ROMBASE in booter */ + /* indeed, plus need to MAP THE ROM !! */ + + if (mac_bi_data.rombase == 0) + mac_bi_data.rombase = 0x40800000; /* works on some */ rom_reset = (void *) (mac_bi_data.rombase + 0xa); @@ -318,12 +319,22 @@ void mac_reset(void) printk("ROM reset hook: %p\n", *reset_hook); rom_reset = *reset_hook; #endif + if (macintosh_config->ident == MAC_MODEL_SE30) { + /* + * MSch: Machines known to crash on ROM reset ... + */ + printk("System halted.\n"); + while(1); + } else { + save_flags(flags); + cli(); - rom_reset(); + rom_reset(); - restore_flags(flags); + restore_flags(flags); + } - /* We never make it this far... */ + /* We never make it this far... it usually panics above. */ printk ("Restart failed. Please restart manually.\n"); /* XXX - delay do we need to spin here ? */ |