diff -u --recursive --new-file v2.1.128/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.128/linux/Documentation/Configure.help Thu Nov 12 16:21:17 1998 +++ linux/Documentation/Configure.help Sun Nov 15 10:12:01 1998 @@ -1759,6 +1759,58 @@ which includes a server that supports the frame buffer device directly (XF68_FBDev). +Matrox unified accelerated driver +CONFIG_FB_MATROX + Say Y here if you have Matrox Millenium, Matrox Millenium II, Matrox + Mystique, Matrox Mystique 220 or Matrox Productiva G100 in your box. + At this time, G100 support is untested and G200 support does not + exist at all. If you want, you can select M, in this case module + matroxfb.o will be created. + You can pass parameters into driver if it is compiled into kernel by + specifying "video=matrox:XXX", where meaning of XXX you can found at + the end of main source file (drivers/video/matroxfb.c) at boottime. + Same parameters can be passed into insmod if driver is used as + module. + +Matrox Millenium support +CONFIG_FB_MATROX_MILLENIUM + Say Y here if you have Matrox Millenium or Matrox Millenium II in the + box. If you select "Advanced lowlevel driver options", you should + check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp packed pixel, 24 + bpp packed pixel and 32 bpp packed pixel. You can also use font + widths different from 8. + +Matrox Mystique support +CONFIG_FB_MATROX_MYSTIQUE + Say Y here if you have Matrox Mystique or Matrox Mystique 220 in the + box. If you select "Advanced lowlevel driver options", you should + check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed pixel + and 32 bpp packed pixel. You can also use font widths different + from 8. + +Matrox G100 support +CONFIG_FB_MATROX_G100 + Say Y here if you have Matrox Productiva G100 in the box. But THIS + DRIVER IS NOT TESTED BECAUSE OF I HAVE NO G100 board and G100 + technical sheets are top secret at this time. But driver should not + cause any damage to your computer. + If you select "Advanced lowlevel driver options", you should check + 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed pixel and + 32 bpp packed pixel. You can also use font widths different from 8. + +Matrox unified driver multihead support +CONFIG_FB_MATROX_MULTIHEAD + Say Y here if you have more than one (supported) Matrox device in + computer and you want to use all of them. If you have only one + device, you should say N because of driver compiled with Y is larger + and a bit slower, especially on ia32 (ix86). + If you compiled driver as module, you are VERY interested in speed + and you can use 40KB of memory per each Matrox device, you can + compile driver without multihead support and instead of it insmod + more module instances. In this case, you MUST specify parameter dev=N + to insmod, where N is sequential number of Matrox device (0 = first, + 1 = second and so on). + MDA text console (dual-headed) CONFIG_MDA_CONSOLE Say Y here if you have an old MDA or monochrome Hercules graphics @@ -3740,6 +3792,13 @@ The module will be called fdomain.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. +Future Domain MCS-600/700 SCSI support +CONFIG_SCSI_FD_MCS + This is support for Future Domain MCS 600/700 MCA SCSI adapters. Some + PS/2s are also equipped with IBM Fast SCSI Adapter/A which is an OEM + of the MCS 700. This driver also supports Reply SB16/SCSI card (the + SCSI part). It supports multiple adapters in the same system. + Generic NCR5380/53c400 SCSI support CONFIG_SCSI_GENERIC_NCR5380 This is the generic NCR family of SCSI controllers, not to be @@ -3878,9 +3937,8 @@ 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. @@ -3895,12 +3953,10 @@ 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. @@ -5013,9 +5069,9 @@ Comtrol Hostess SV-11 support CONFIG_HOSTESS_SV11 - This is a network card for high speed synchronous serial links. It - is commonly used to connect to Cisco equipment over HSSI links. At - this point, the driver can only be compiled as a module. + This is a network card for low speed synchronous serial links, at + up to 256Kbits. It supports both PPP and Cisco HDLC + At this point, the driver can only be compiled as a module. WAN Drivers CONFIG_WAN_DRIVERS @@ -5576,7 +5632,7 @@ is for you, read the Ethernet-HOWTO, available via FTP (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. -AT1700 support +AT1700/1720 support CONFIG_AT1700 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in @@ -9627,7 +9683,7 @@ 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 @@ -9637,7 +9693,7 @@ 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 @@ -10213,7 +10269,7 @@ # 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 -u --recursive --new-file v2.1.128/linux/Documentation/networking/ltpc.txt linux/Documentation/networking/ltpc.txt --- v2.1.128/linux/Documentation/networking/ltpc.txt Sat May 2 14:19:51 1998 +++ linux/Documentation/networking/ltpc.txt Fri Nov 13 10:29:43 1998 @@ -6,18 +6,37 @@ driver applies only to the one with the 65c02 processor chip on it. To include it in the kernel, select the CONFIG_LTPC switch in the -configuration dialog; at this time (kernel 2.1.23) compiling it as -a module will not work. +configuration dialog. You can also compile it as a module. + +While the driver will attempt to autoprobe the I/O port address, IRQ +line, and DMA channel of the card, this does not always work. For +this reason, you should be prepared to supply these parameters +yourself. (see "Card Configuration" below for how to determine or +change the settings on your card) + +When the driver is compiled into the kernel, you can add a line such +as the following to your /etc/lilo.conf: + + append="ltpc=0x240,9,1" + +where the parameters (in order) are the port address, IRQ, and DMA +channel. The second and third values can be omitted, in which case +the driver will try to determine them itself. + +If you load the driver as a module, you can pass the parameters "io=", +"irq=", and "dma=" on the command line with insmod or modprobe, or add +them as options in /etc/conf.modules: + + alias lt0 ltpc # autoload the module when the interface is configured + options ltpc io=0x240 irq=9 dma=1 Before starting up the netatalk demons (perhaps in rc.local), you need to add a line such as: -/sbin/ifconfig ltalk0 127.0.0.42 - + /sbin/ifconfig lt0 127.0.0.42 -The driver will autoprobe, and you should see a message like: -"LocalTalk card found at 240, IR9, DMA1." -at bootup. +The address is unimportant - however, the card needs to be configured +with ifconfig so that Netatalk can find it. The appropriate netatalk configuration depends on whether you are attached to a network that includes AppleTalk routers or not. If, @@ -25,22 +44,22 @@ printers, you need to set up netatalk to "seed". The way I do this is to have the lines -dummy -seed -phase 2 -net 2000 -addr 2000.26 -zone "1033" -ltalk0 -seed -phase 1 -net 1033 -addr 1033.27 -zone "1033" + dummy -seed -phase 2 -net 2000 -addr 2000.26 -zone "1033" + lt0 -seed -phase 1 -net 1033 -addr 1033.27 -zone "1033" in my atalkd.conf. What is going on here is that I need to fool netatalk into thinking that there are two AppleTalk interfaces -present -- otherwise it refuses to seed. This is a hack, and a -more permanent solution would be to alter the netatalk code. -Note that the dummy driver needs to accept multicasts also -- earlier -versions of dummy.c may need to be patched. - +present; otherwise, it refuses to seed. This is a hack, and a more +permanent solution would be to alter the netatalk code. Also, make +sure you have the correct name for the dummy interface - If it's +compiled as a module, you will need to refer to it as "dummy0" or some +such. If you are attached to an extended AppleTalk network, with routers on it, then you don't need to fool around with this -- the appropriate line in atalkd.conf is -ltalk0 -phase 1 + lt0 -phase 1 -------------------------------------- @@ -74,19 +93,32 @@ -------------------------------------- IP: - Many people are interested in this driver in order to use IP -when LocalTalk, but no Ethernet, is available. While the code to do -this is not strictly speaking part of this driver, an experimental -version is available which seems to work under kernel 2.0.xx. It is -not yet functional in the 2.1.xx kernels. + +Yes, it is possible to do IP over LocalTalk. However, you can't just +treat the LocalTalk device like an ordinary Ethernet device, even if +that's what it looks like to Netatalk. + +Instead, you follow the same procedure as for doing IP in EtherTalk. +See Documentation/networking/ipddp.txt for more information about the +kernel driver and userspace tools needed. -------------------------------------- BUGS: -2.0.xx: - -2.1.xx: The module support doesn't work yet. +IRQ autoprobing often doesn't work on a cold boot. To get around +this, either compile the driver as a module, or pass the parameters +for the card to the kernel as described above. + +Also, as usual, autoprobing is not recommended when you use the driver +as a module. (though it usually works at boot time, at least) + +Polled mode is *really* slow sometimes, but this seems to depend on +the configuration of the network. + +It may theoretically be possible to use two LTPC cards in the same +machine, but this is unsupported, so if you really want to do this, +you'll probably have to hack the initialization code a bit. ______________________________________ @@ -96,3 +128,4 @@ -- Bradford Johnson +-- Updated 11/09/1998 by David Huggins-Daines diff -u --recursive --new-file v2.1.128/linux/Documentation/sysctl/README linux/Documentation/sysctl/README --- v2.1.128/linux/Documentation/sysctl/README Wed Jun 24 22:54:02 1998 +++ linux/Documentation/sysctl/README Fri Nov 13 10:07:26 1998 @@ -1,4 +1,4 @@ -Documentation for /proc/sys/*/* version 0.1 +Documentation for /proc/sys/ kernel version 2.1.128 (c) 1998, Rik van Riel 'Why', I hear you ask, 'would anyone even _want_ documentation @@ -12,6 +12,9 @@ Furthermore, the programmers who built sysctl have built it to be actually used, not just for the fun of programming it :-) +If you prefer HTML, feel free to visit the Linux-MM homepage +... + ============================================================== Legal blurb: @@ -58,9 +61,9 @@ debug/ dev/ device specific information (eg dev/cdrom/info) fs/ specific filesystems + filehandle, inode, dentry and quota tuning binfmt_misc kernel/ global kernel info / tuning - open file / inode tuning miscellaneous stuff net/ networking stuff, for documentation look in: diff -u --recursive --new-file v2.1.128/linux/Documentation/sysctl/fs.txt linux/Documentation/sysctl/fs.txt --- v2.1.128/linux/Documentation/sysctl/fs.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/sysctl/fs.txt Fri Nov 13 10:07:26 1998 @@ -0,0 +1,116 @@ +Documentation for /proc/sys/fs/* kernel version 2.1.128 + (c) 1998, Rik van Riel + +For general info and legal blurb, please look in README. + +============================================================== + +This file contains documentation for the sysctl files in +/proc/sys/fs/ and is valid for Linux kernel version 2.1. + +The files in this directory can be used to tune and monitor +miscellaneous and general things in the operation of the Linux +kernel. Since some of the files _can_ be used to screw up your +system, it is advisable to read both documentation and source +before actually making adjustments. + +Currently, these files are in /proc/sys/fs: +- dentry-state +- dquot-max +- dquot-nr +- file-max +- file-nr +- inode-max +- inode-nr +- inode-state + +Documentation for the files in /proc/sys/fs/binfmt_misc is +in Documentation/binfmt_misc.txt. + +============================================================== + +dentry-state: + +From linux/fs/dentry.c: +-------------------------------------------------------------- +struct { + int nr_dentry; + int nr_unused; + int age_limit; /* age in seconds */ + int want_pages; /* pages requested by system */ + int dummy[2]; +} dentry_stat = {0, 0, 45, 0,}; +-------------------------------------------------------------- + +Dentries are dynamically allocated and deallocated, and +nr_dentry seems to be 0 all the time. Hence it's safe to +assume that only nr_unused, age_limit and want_pages are +used. Nr_unused seems to be exactly what its name says. +Age_limit is the age in seconds after which dcache entries +can be reclaimed when memory is short and want_pages is +nonzero when shrink_dcache_pages() has been called and the +dcache isn't pruned yet. + +============================================================== + +dquot-max & dquot-nr: + +The file dquot-max shows the maximum number of cached disk +quota entries. + +The file dquot-nr shows the number of allocated disk quota +entries and the number of free disk quota entries. + +If the number of free cached disk quotas is very low and +you have some awesome number of simultaneous system users, +you might want to raise the limit. + +============================================================== + +file-max & file-nr: + +The kernel allocates file handles dynamically, but as yet it +doesn't free them again. + +The value in file-max denotes the maximum number of file- +handles that the Linux kernel will allocate. When you get lots +of error messages about running out of file handles, you might +want to increase this limit. + +The three values in file-nr denote the number of allocated +file handles, the number of used file handles and the maximum +number of file handles. When the allocated file handles come +close to the maximum, but the number of actually used ones is +far behind, you've encountered a peak in your usage of file +handles and you don't need to increase the maximum. + +============================================================== + +inode-max, inode-nr & inode-state: + +As with file handles, the kernel allocates the inode structures +dynamically, but can't free them yet. + +The value in inode-max denotes the maximum number of inode +handlers. This value should be 3-4 times larger than the value +in file-max, since stdin, stdout and network sockets also +need an inode struct to handle them. When you regularly run +out of inodes, you need to increase this value. + +The file inode-nr contains the first two items from +inode-state, so we'll skip to that file... + +Inode-state contains three actual numbers and four dummies. +The actual numbers are, in order of appearance, nr_inodes, +nr_free_inodes and preshrink. + +Nr_inodes stands for the number of inodes the system has +allocated, this can be slightly more than inode-max because +Linux allocates them one pageful at a time. + +Nr_free_inodes represents the number of free inodes (?) and +preshrink is nonzero when the nr_inodes > inode-max and the +system needs to prune the inode list instead of allocating +more. + + diff -u --recursive --new-file v2.1.128/linux/Documentation/sysctl/kernel.txt linux/Documentation/sysctl/kernel.txt --- v2.1.128/linux/Documentation/sysctl/kernel.txt Thu Nov 12 16:21:17 1998 +++ linux/Documentation/sysctl/kernel.txt Fri Nov 13 10:07:26 1998 @@ -1,4 +1,4 @@ -Documentation for /proc/sys/kernel/* version 0.1 +Documentation for /proc/sys/kernel/* kernel version 2.1.128 (c) 1998, Rik van Riel For general info and legal blurb, please look in README. @@ -14,26 +14,27 @@ system, it is advisable to read both documentation and source before actually making adjustments. -Currently, these files are in /proc/sys/kernel: +Currently, these files might (depending on your configuration) +show up in /proc/sys/kernel: - acct - ctrl-alt-del - dentry-state - domainname -- file-max -- file-nr - hostname -- inode-max -- inode-nr -- inode-state +- htab-reclaim [ PPC only ] +- java-appletviewer [ binfmt_java, obsolete ] +- java-interpreter [ binfmt_java, obsolete ] - modprobe ==> Documentation/kmod.txt - osrelease - ostype - panic +- powersave-nap [ PPC only ] - printk - real-root-dev ==> Documentation/initrd.txt -- reboot-cmd ==> SPARC specific -- securelevel +- reboot-cmd [ SPARC only ] +- sg-big-buff [ generic SCSI device (sg) ] - version +- zero-paged [ PPC only ] ============================================================== @@ -69,30 +70,6 @@ ============================================================== -dentry-state: - -From linux/fs/dentry.c: --------------------------------------------------------------- -struct { - int nr_dentry; - int nr_unused; - int age_limit; /* age in seconds */ - int want_pages; /* pages requested by system */ - int dummy[2]; -} dentry_stat = {0, 0, 45, 0,}; --------------------------------------------------------------- - -Dentries are dynamically allocated and deallocated, and -nr_dentry seems to be 0 all the time. Hence it's safe to -assume that only nr_unused, age_limit and want_pages are -used. Nr_unused seems to be exactly what its name says. -Age_limit is the age in seconds after which dcache entries -can be reclaimed when memory is short and want_pages is -nonzero when shrink_dcache_pages() has been called and the -dcache isn't pruned yet. - -============================================================== - domainname & hostname: These files can be controlled to set the domainname and @@ -104,52 +81,12 @@ ============================================================== -file-max & file-nr: - -The kernel allocates file handles dynamically, but as yet it -doesn't free them again. - -The value in file-max denotes the maximum number of file- -handles that the Linux kernel will allocate. When you get lots -of error messages about running out of file handles, you might -want to increase this limit. - -The three values in file-nr denote the number of allocated -file handles, the number of used file handles and the maximum -number of file handles. When the allocated file handles come -close to the maximum, but the number of actually used ones is -far behind, you've encountered a peak in your usage of file -handles and you don't need to increase the maximum. - -============================================================== - -inode-max, inode-nr & inode-state: - -As with file handles, the kernel allocates the inode structures -dynamically, but can't free them yet. - -The value in inode-max denotes the maximum number of inode -handlers. This value should be 3-4 times larger than the value -in file-max, since stdin, stdout and network sockets also -need an inode struct to handle them. When you regularly run -out of inodes, you need to increase this value. - -The file inode-nr contains the first two items from -inode-state, so we'll skip to that file... - -Inode-state contains three actual numbers and four dummies. -The actual numbers are, in order of appearance, nr_inodes, -nr_free_inodes and preshrink. - -Nr_inodes stands for the number of inodes the system has -allocated, this can be slightly more than inode-max because -Linux allocates them one pageful at a time. - -Nr_free_inodes represents the number of free inodes (?) and -preshrink is nonzero when the nr_inodes > inode-max and the -system needs to prune the inode list instead of allocating -more. +htab-reclaim: (PPC only) +Setting this to a non-zero value, the PowerPC htab +(see Documentation/powerpc/ppc_htab.txt) is pruned +each time the system hits the idle loop. + ============================================================== osrelease, ostype & version: @@ -177,6 +114,13 @@ ============================================================== +powersave-nap: (PPC only) + +If set, Linux-PPC will use the 'nap' mode of powersaving, +otherwise the 'doze' mode will be used. + +============================================================== + printk: The four values in printk denote: console_loglevel, @@ -202,27 +146,30 @@ ============================================================== -securelevel: +reboot-cmd: (Sparc only) -When the value in this file is nonzero, root is prohibited -from: -- changing the immutable and append-only flags on files -- changing sysctl things (limited ???) +??? This seems to be a way to give an argument to the Sparc +ROM/Flash boot loader. Maybe to tell it what to do after +rebooting. ??? ============================================================== -real-root-dev: (CONFIG_INITRD only) +sg-big-buff: -This file is used to configure the real root device when using -an initial ramdisk to configure the system before switching to -the 'real' root device. See linux/Documentation/initrd.txt for -more info. +This file shows the size of the generic SCSI (sg) buffer. +You can't tune it just yet, but you could change it on +compile time by editing include/scsi/sg.h and changing +the value of SG_BIG_BUFF. -============================================================== +There shouldn't be any reason to change this value. If +you can come up with one, you probably know what you +are doing anyway :) -reboot-cmd: (Sparc only) +============================================================== -??? This seems to be a way to give an argument to the Sparc -ROM/Flash boot loader. Maybe to tell it what to do after -rebooting. ??? +zero-paged: (PPC only) +When enabled (non-zero), Linux-PPC will pre-zero pages in +the idle loop, possibly speeding up get_free_pages. Since +this only affects what the idle loop is doing, you should +enable this and see if anything changes. diff -u --recursive --new-file v2.1.128/linux/Documentation/sysctl/vm.txt linux/Documentation/sysctl/vm.txt --- v2.1.128/linux/Documentation/sysctl/vm.txt Wed Jun 24 22:54:02 1998 +++ linux/Documentation/sysctl/vm.txt Fri Nov 13 10:07:26 1998 @@ -1,4 +1,4 @@ -Documentation for /proc/sys/vm/* version 0.1 +Documentation for /proc/sys/vm/* kernel version 2.1.128 (c) 1998, Rik van Riel For general info and legal blurb, please look in README. @@ -20,8 +20,8 @@ - kswapd - overcommit_memory - pagecache +- pagetable_cache - swapctl -- swapout_interval ============================================================== @@ -56,7 +56,7 @@ } bdf_prm = {{40, 500, 64, 256, 15, 30*HZ, 5*HZ, 1884, 2}}; -------------------------------------------------------------- -The first parameter governs the maximum number of of dirty +The first parameter governs the maximum number of dirty buffers in the buffer cache. Dirty means that the contents of the buffer still have to be written to disk (as opposed to a clean buffer, which can just be forgotten about). @@ -101,8 +101,9 @@ min_percent -- this is the minimum percentage of memory that should be spent on buffer memory borrow_percent -- when Linux is short on memory, and the - buffer cache uses more memory, free pages - are stolen from it + buffer cache uses more memory than this, + the MM subsystem will prune the buffercache + more heavily than other memory max_percent -- this is the maximum amount of memory that can be used for buffer memory @@ -112,25 +113,17 @@ This file contains the values in the struct freepages. That struct contains three members: min, low and high. -Although the goal of the Linux memory management subsystem -is to avoid fragmentation and make large chunks of free -memory (so that we can hand out DMA buffers and such), there -still are some page-based limits in the system, mainly to -make sure we don't waste too much memory trying to get large -free area's. - The meaning of the numbers is: freepages.min When the number of free pages in the system reaches this number, only the kernel can allocate more memory. -freepages.low If memory is too fragmented, the swapout - daemon is started, except when the number - of free pages is larger than freepages.low. -freepages.high The swapping daemon exits when memory is - sufficiently defragmented, when the number - of free pages reaches freepages.high or when - it has tried the maximum number of times. +freepages.low If the number of free pages gets below this + point, the kernel starts swapping agressively. +freepages.high The kernel tries to keep up to this amount of + memory free; if memory comes below this point, + the kernel gently starts swapping in the hopes + that it never has to do real agressive swapping. ============================================================== @@ -210,7 +203,8 @@ This file does exactly the same as buffermem, only this file controls the struct page_cache, and thus controls -the amount of memory allowed for memory mapping of files. +the amount of memory allowed for memory mapping and generic +caching of files. You don't want the minimum level to be too low, otherwise your system might thrash when memory is tight or fragmentation @@ -218,6 +212,23 @@ ============================================================== +pagetable_cache: + +The kernel keeps a number of page tables in a per-processor +cache (this helps a lot on SMP systems). The cache size for +each processor will be between the low and the high value. + +On a low-memory, single CPU system you can safely set these +values to 0 so you don't waste the memory. On SMP systems it +is used so that the system can do fast pagetable allocations +without having to aquire the kernel memory lock. + +For large systems, the settings are probably OK. For normal +systems they won't hurt a bit. For small systems (<16MB ram) +it might be advantageous to set both values to 0. + +============================================================== + swapctl: This file contains no less than 8 variables. @@ -274,14 +285,4 @@ might want to either increase sc_bufferout_weight, or decrease the value of sc_pageout_weight. -============================================================== - -swapout_interval: - -The single value in this file controls the amount of time -between successive wakeups of kswapd when nr_free_pages is -between free_pages_low and free_pages_high. The default value -of HZ/4 is usually right, but when kswapd can't keep up with -the number of allocations in your system, you might want to -decrease this number. diff -u --recursive --new-file v2.1.128/linux/Makefile linux/Makefile --- v2.1.128/linux/Makefile Thu Nov 12 16:21:17 1998 +++ linux/Makefile Thu Nov 12 16:21:37 1998 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 128 +SUBLEVEL = 129 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff -u --recursive --new-file v2.1.128/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.1.128/linux/arch/i386/kernel/i386_ksyms.c Tue Jul 28 14:21:07 1998 +++ linux/arch/i386/kernel/i386_ksyms.c Fri Nov 13 10:29:44 1998 @@ -98,6 +98,9 @@ EXPORT_SYMBOL(mca_set_adapter_procfn); EXPORT_SYMBOL(mca_isenabled); EXPORT_SYMBOL(mca_isadapter); +EXPORT_SYMBOL(mca_mark_as_used); +EXPORT_SYMBOL(mca_mark_as_unused); +EXPORT_SYMBOL(mca_find_unused_adapter); #endif #ifdef CONFIG_VT diff -u --recursive --new-file v2.1.128/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.1.128/linux/arch/i386/kernel/time.c Thu Nov 12 16:21:18 1998 +++ linux/arch/i386/kernel/time.c Sun Nov 15 11:14:36 1998 @@ -526,9 +526,9 @@ /* 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 @@ * 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/Makefile linux/arch/ppc/Makefile --- v2.1.128/linux/arch/ppc/Makefile Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/Makefile Sun Nov 15 10:51:41 1998 @@ -16,6 +16,8 @@ ifeq ($(shell uname -m),ppc) CHECKS = checks +else +CROSS_COMPILE = ppc-linux-elf- endif ASFLAGS = diff -u --recursive --new-file v2.1.128/linux/arch/ppc/amiga/amiints.c linux/arch/ppc/amiga/amiints.c --- v2.1.128/linux/arch/ppc/amiga/amiints.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/amiga/amiints.c Sun Nov 15 10:51:41 1998 @@ -108,6 +108,11 @@ 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 @@ } 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c --- v2.1.128/linux/arch/ppc/amiga/config.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/amiga/config.c Sun Nov 15 10:51:41 1998 @@ -434,10 +434,6 @@ */ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/amiga/time.c linux/arch/ppc/amiga/time.c --- v2.1.128/linux/arch/ppc/amiga/time.c Thu Aug 6 14:06:29 1998 +++ linux/arch/ppc/amiga/time.c Sun Nov 15 10:51:41 1998 @@ -1,3 +1,4 @@ +#include /* CONFIG_HEARTBEAT */ #include #include #include @@ -68,3 +69,24 @@ } +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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c --- v2.1.128/linux/arch/ppc/kernel/chrp_setup.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/chrp_setup.c Sun Nov 15 10:51:43 1998 @@ -39,6 +39,7 @@ #include #include #include +#include extern void hydra_init(void); extern void w83c553f_init(void); @@ -191,7 +192,15 @@ 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 @@ /* 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 @@ * 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/feature.c linux/arch/ppc/kernel/feature.c --- v2.1.128/linux/arch/ppc/kernel/feature.c Wed Dec 31 16:00:00 1969 +++ linux/arch/ppc/kernel/feature.c Sun Nov 15 10:51:43 1998 @@ -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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S --- v2.1.128/linux/arch/ppc/kernel/head.S Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/head.S Sun Nov 15 10:51:43 1998 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/idle.c linux/arch/ppc/kernel/idle.c --- v2.1.128/linux/arch/ppc/kernel/idle.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/idle.c Sun Nov 15 10:51:43 1998 @@ -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 @@ 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,14 +80,8 @@ */ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c --- v2.1.128/linux/arch/ppc/kernel/irq.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/irq.c Sun Nov 15 10:51:43 1998 @@ -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 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 @@ #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 @@ 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 @@ }; /* 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 @@ /* 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 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ #endif /* __SMP__ */ - asmlinkage void do_IRQ(struct pt_regs *regs) { int irq; @@ -627,9 +659,6 @@ 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 @@ 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 @@ * * 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 @@ } #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 @@ 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 @@ 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 @@ 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 @@ #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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ } #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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S --- v2.1.128/linux/arch/ppc/kernel/misc.S Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/misc.S Sun Nov 15 10:51:43 1998 @@ -363,9 +363,25 @@ 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 @@ #define __NR__exit __NR_exit SYSCALL(idle) -SYSCALL(setup) SYSCALL(sync) SYSCALL(setsid) SYSCALL(write) @@ -490,12 +505,12 @@ .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 @@ .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 @@ .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 @@ .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 @@ .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 @@ .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 @@ .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 @@ .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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c --- v2.1.128/linux/arch/ppc/kernel/pci.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/pci.c Sun Nov 15 10:51:43 1998 @@ -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 @@ get_property(find_path_device("/"), "model", NULL),3) ) { isa_io_base = 0xfe000000; - set_config_access_method(raven); + set_config_access_method(grackle); } else { diff -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c --- v2.1.128/linux/arch/ppc/kernel/pmac_pci.c Thu Aug 6 14:06:29 1998 +++ linux/arch/ppc/kernel/pmac_pci.c Sun Nov 15 10:51:43 1998 @@ -40,7 +40,6 @@ #define BANDIT_COHERENT 0x40 __pmac - void *pci_io_base(unsigned int bus) { struct bridge_data *bp; @@ -50,6 +49,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c --- v2.1.128/linux/arch/ppc/kernel/pmac_setup.c Fri Oct 23 22:01:20 1998 +++ linux/arch/ppc/kernel/pmac_setup.c Sun Nov 15 10:51:43 1998 @@ -49,9 +49,9 @@ #include #include #include -#include #include #include +#include #include "time.h" unsigned char drive_info; @@ -64,7 +64,6 @@ static void ohare_init(void); __pmac - int pmac_get_cpuinfo(char *buffer) { @@ -151,6 +150,7 @@ #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 @@ * 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 @@ 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 @@ __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_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 @@ #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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/pmac_support.c linux/arch/ppc/kernel/pmac_support.c --- v2.1.128/linux/arch/ppc/kernel/pmac_support.c Fri May 8 23:14:45 1998 +++ linux/arch/ppc/kernel/pmac_support.c Sun Nov 15 10:51:43 1998 @@ -25,8 +25,7 @@ #define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */ -__pmac - +__init void pmac_nvram_init(void) { struct device_node *dp; diff -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c --- v2.1.128/linux/arch/ppc/kernel/ppc_ksyms.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/ppc_ksyms.c Sun Nov 15 10:51:43 1998 @@ -24,6 +24,7 @@ #include #include #include +#include #define __KERNEL_SYSCALLS__ #include @@ -100,7 +101,6 @@ 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(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(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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c --- v2.1.128/linux/arch/ppc/kernel/prep_pci.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/prep_pci.c Sun Nov 15 10:51:43 1998 @@ -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 @@ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c --- v2.1.128/linux/arch/ppc/kernel/prep_setup.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/prep_setup.c Sun Nov 15 10:51:44 1998 @@ -196,7 +196,7 @@ 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 @@ } } } -#endif /* CONFIG_CS4232 */ - +#endif /* CONFIG_SOUND_CS4232 */ /*print_residual_device_info();*/ request_region(0x20,0x20,"pic1"); diff -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c --- v2.1.128/linux/arch/ppc/kernel/process.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/process.c Sun Nov 15 10:51:44 1998 @@ -163,14 +163,19 @@ #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 @@ { int res; + lock_kernel(); res = do_fork(SIGCHLD, regs->gpr[1], regs); /* only parent returns here */ @@ -404,18 +410,23 @@ { 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c --- v2.1.128/linux/arch/ppc/kernel/prom.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/prom.c Sun Nov 15 10:51:44 1998 @@ -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 @@ 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 @@ 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 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 @@ #define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long)) -__openfirmware +__init static void prom_exit() { @@ -148,7 +182,7 @@ ; } -__openfirmware +__init void prom_enter(void) { @@ -161,7 +195,7 @@ RELOC(prom)(&args); } -__openfirmware +__init static void * call_prom(const char *service, int nargs, int nret, ...) { @@ -183,13 +217,23 @@ 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 @@ * 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 @@ 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 @@ * 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 @@ * 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 @@ return ALIGN(mem); } -__openfirmware +__init static int prom_next_node(phandle *nodep) { @@ -415,7 +476,7 @@ /* * 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 @@ 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 @@ * 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 @@ 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 @@ 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 @@ * 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 @@ } } -__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 @@ 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 @@ return mem_start; } -__openfirmware +__init static unsigned long interpret_dbdma_props(struct device_node *np, unsigned long mem_start) { @@ -710,7 +817,7 @@ return mem_start; } -__openfirmware +__init static unsigned long interpret_macio_props(struct device_node *np, unsigned long mem_start) { @@ -748,18 +855,28 @@ 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 @@ return mem_start; } -__openfirmware +__init static unsigned long interpret_root_props(struct device_node *np, unsigned long mem_start) { @@ -876,6 +993,30 @@ 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 @@ 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 @@ return 0; } +#if 0 __openfirmware void print_properties(struct device_node *np) @@ -1001,7 +1141,9 @@ } } } +#endif +/* this can be called after setup -- Cort */ __openfirmware int call_rtas(const char *service, int nargs, int nret, @@ -1038,7 +1180,7 @@ return u.words[nargs+3]; } -__openfirmware +__init void abort() { @@ -1048,3 +1190,563 @@ #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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/residual.c linux/arch/ppc/kernel/residual.c --- v2.1.128/linux/arch/ppc/kernel/residual.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/residual.c Sun Nov 15 10:51:44 1998 @@ -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 @@ /* 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ #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 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 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 @@ 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 @@ } 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 @@ } - -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 @@ /* * Spit out some info about residual data */ -#if 0 void print_residual_device_info(void) { int i; @@ -764,7 +763,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c --- v2.1.128/linux/arch/ppc/kernel/setup.c Fri Oct 9 13:27:06 1998 +++ linux/arch/ppc/kernel/setup.c Sun Nov 15 10:51:44 1998 @@ -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 @@ cuda_poll(); break; case ADB_VIAPMU: - pmu_request(&req, NULL, 1, PMU_RESET); - for (;;) - pmu_poll(); + pmu_restart(); break; default: } @@ -206,10 +205,7 @@ 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 @@ { #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 @@ 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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c --- v2.1.128/linux/arch/ppc/kernel/signal.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/signal.c Sun Nov 15 10:51:44 1998 @@ -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 @@ 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 @@ || 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c --- v2.1.128/linux/arch/ppc/kernel/smp.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/smp.c Sun Nov 15 10:51:45 1998 @@ -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 @@ 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 @@ * 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 @@ { 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_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 @@ 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 @@ __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 @@ 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 @@ 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 @@ 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 @@ */ 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 @@ } /* 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(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 @@ { 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c --- v2.1.128/linux/arch/ppc/kernel/time.c Thu Aug 6 14:06:29 1998 +++ linux/arch/ppc/kernel/time.c Sun Nov 15 10:51:45 1998 @@ -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 @@ #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 -u --recursive --new-file v2.1.128/linux/arch/ppc/lib/locks.c linux/arch/ppc/lib/locks.c --- v2.1.128/linux/arch/ppc/lib/locks.c Thu Aug 6 14:06:29 1998 +++ linux/arch/ppc/lib/locks.c Sun Nov 15 10:51:45 1998 @@ -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 @@ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c --- v2.1.128/linux/arch/ppc/mm/fault.c Wed Sep 9 14:51:06 1998 +++ linux/arch/ppc/mm/fault.c Sun Nov 15 10:51:45 1998 @@ -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 -u --recursive --new-file v2.1.128/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c --- v2.1.128/linux/arch/ppc/mm/init.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/mm/init.c Sun Nov 15 10:51:45 1998 @@ -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 @@ * (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 @@ 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 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 @@ 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; - } + 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; - 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) + 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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/arch/ppc/pmac_defconfig linux/arch/ppc/pmac_defconfig --- v2.1.128/linux/arch/ppc/pmac_defconfig Sun Nov 8 14:02:44 1998 +++ linux/arch/ppc/pmac_defconfig Sun Nov 15 10:51:45 1998 @@ -35,16 +35,20 @@ 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_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_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_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_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_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_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_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_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_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 -u --recursive --new-file v2.1.128/linux/arch/ppc/prep_defconfig linux/arch/ppc/prep_defconfig --- v2.1.128/linux/arch/ppc/prep_defconfig Sun Nov 8 14:02:44 1998 +++ linux/arch/ppc/prep_defconfig Sun Nov 15 10:51:45 1998 @@ -41,7 +41,7 @@ # 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 -u --recursive --new-file v2.1.128/linux/drivers/block/Config.in linux/drivers/block/Config.in --- v2.1.128/linux/drivers/block/Config.in Fri Oct 23 22:01:20 1998 +++ linux/drivers/block/Config.in Fri Nov 13 10:29:44 1998 @@ -77,7 +77,7 @@ fi fi if [ "$CONFIG_MCA" = "y" ]; then - bool 'PS/2 ESDI hard disk support' CONFIG_BLK_DEV_PS2 + tristate 'PS/2 ESDI hard disk support' CONFIG_BLK_DEV_PS2 fi if [ "$CONFIG_ZORRO" = "y" ]; then tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM @@ -94,7 +94,9 @@ comment 'Additional Block Devices' tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP -tristate 'Network block device support' CONFIG_BLK_DEV_NBD +if [ "$CONFIG_NET" = "y" ]; then + tristate 'Network block device support' CONFIG_BLK_DEV_NBD +fi bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then tristate ' Linear (append) mode' CONFIG_MD_LINEAR diff -u --recursive --new-file v2.1.128/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c --- v2.1.128/linux/drivers/block/amiflop.c Wed Aug 26 11:37:34 1998 +++ linux/drivers/block/amiflop.c Sun Nov 15 11:23:08 1998 @@ -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"); @@ -1858,20 +1858,6 @@ blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; 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; diff -u --recursive --new-file v2.1.128/linux/drivers/block/ide-pmac.c linux/drivers/block/ide-pmac.c --- v2.1.128/linux/drivers/block/ide-pmac.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/block/ide-pmac.c Sun Nov 15 10:51:46 1998 @@ -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 @@ 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 @@ /* 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 @@ 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_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 @@ ++i; } + pmac_ide_count = i; } #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC diff -u --recursive --new-file v2.1.128/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c --- v2.1.128/linux/drivers/block/ide-probe.c Thu Sep 17 17:53:35 1998 +++ linux/drivers/block/ide-probe.c Fri Nov 13 09:55:31 1998 @@ -78,8 +78,18 @@ ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap); id->model[sizeof(id->model)-1] = '\0'; /* we depend on this a lot! */ - drive->present = 1; printk("%s: %s, ", drive->name, id->model); + drive->present = 1; + + /* + * Prevent long system lockup probing later for non-existant + * slave drive if the hwif is actually a Kodak CompactFlash card. + */ + if (!strcmp(id->model, "KODAK ATA_FLASH")) { + ide_drive_t *mate = &HWIF(drive)->drives[1^drive->select.b.unit]; + mate->present = 0; + mate->noprobe = 1; + } /* * Check for an ATAPI device diff -u --recursive --new-file v2.1.128/linux/drivers/block/sl82c105.c linux/drivers/block/sl82c105.c --- v2.1.128/linux/drivers/block/sl82c105.c Thu Aug 6 14:06:31 1998 +++ linux/drivers/block/sl82c105.c Sun Nov 15 10:51:46 1998 @@ -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; @@ -36,38 +31,4 @@ pci_read_config_dword(dev, 0x40, &t32); 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 -u --recursive --new-file v2.1.128/linux/drivers/block/swim3.c linux/drivers/block/swim3.c --- v2.1.128/linux/drivers/block/swim3.c Sun Nov 8 14:02:51 1998 +++ linux/drivers/block/swim3.c Sun Nov 15 10:51:46 1998 @@ -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 @@ 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 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 @@ 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 @@ 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 @@ 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 void do_fd_request(void) { - start_request(&floppy_states[0]); + int i; + for(i=0;istate == idle && fs->wanted) { @@ -261,11 +272,6 @@ 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 @@ 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 @@ 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 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 @@ { 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 @@ 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 @@ { 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 @@ 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_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 @@ 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 @@ { 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 @@ { 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 @@ 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; + } + + swim = find_devices("swim3"); + while (swim && (floppy_count < MAX_FLOPPIES)) + { + swim3_add_device(swim); + swim = swim->next; + } + + 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; } - if (swims == NULL) - return 0; + return 0; +} - 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); +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 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/block/via82c586.c linux/drivers/block/via82c586.c --- v2.1.128/linux/drivers/block/via82c586.c Thu Sep 17 17:53:35 1998 +++ linux/drivers/block/via82c586.c Fri Nov 13 10:29:44 1998 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/via82C586.c Version 0.01 Aug 16, 1998 + * linux/drivers/block/via82c586.c Version 0.01 Aug 16, 1998 * * Copyright (C) 1998 Michel Aubry * Copyright (C) 1998 Andre Hedrick diff -u --recursive --new-file v2.1.128/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- v2.1.128/linux/drivers/cdrom/cdrom.c Sun Nov 8 14:02:52 1998 +++ linux/drivers/cdrom/cdrom.c Fri Nov 13 10:29:44 1998 @@ -174,7 +174,9 @@ struct cdrom_device_ops * cdo); static void sanitize_format(union cdrom_addr *addr, u_char * curr, u_char requested); +#ifdef CONFIG_SYSCTL static void cdrom_sysctl_register(void); +#endif /* CONFIG_SYSCTL */ static struct cdrom_device_info *topCdromPtr = NULL; struct file_operations cdrom_fops = diff -u --recursive --new-file v2.1.128/linux/drivers/char/adbmouse.c linux/drivers/char/adbmouse.c --- v2.1.128/linux/drivers/char/adbmouse.c Wed Aug 26 11:37:36 1998 +++ linux/drivers/char/adbmouse.c Sun Nov 15 10:51:46 1998 @@ -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 @@ * 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 @@ 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. - */ - - /* - * '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 - */ + 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 (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)); - } + 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]; - add_mouse_randomness(((~buttons & 7) << 16) + ((buf[2]&0x7f) << 8) + (buf[1]&0x7f)); - mouse.buttons = buttons & 7; + 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 @@ 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 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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/char/lp_m68k.c linux/drivers/char/lp_m68k.c --- v2.1.128/linux/drivers/char/lp_m68k.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/lp_m68k.c Sun Nov 15 11:23:23 1998 @@ -477,7 +477,7 @@ 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 @@ #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 -u --recursive --new-file v2.1.128/linux/drivers/char/random.c linux/drivers/char/random.c --- v2.1.128/linux/drivers/char/random.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/random.c Fri Nov 13 10:29:44 1998 @@ -1407,19 +1407,15 @@ switch (cmd) { case RNDGETENTCNT: - retval = verify_area(VERIFY_WRITE, (void *) arg, sizeof(int)); - if (retval) - return(retval); ent_count = random_state.entropy_count; - put_user(ent_count, (int *) arg); + if (put_user(ent_count, (int *) arg)) + return -EFAULT; return 0; case RNDADDTOENTCNT: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - retval = verify_area(VERIFY_READ, (void *) arg, sizeof(int)); - if (retval) - return(retval); - get_user(ent_count, (int *) arg); + if (get_user(ent_count, (int *) arg)) + return -EFAULT; /* * Add i to entropy_count, limiting the result to be * between 0 and POOLBITS. @@ -1446,16 +1442,14 @@ if (!capable(CAP_SYS_ADMIN)) return -EPERM; p = (int *) arg; - retval = verify_area(VERIFY_WRITE, (void *) p, sizeof(int)); - if (retval) - return(retval); ent_count = random_state.entropy_count; - put_user(ent_count, p++); - retval = verify_area(VERIFY_WRITE, (void *) p, sizeof(int)); - if (retval) - return(retval); - get_user(size, p); - put_user(POOLWORDS, p++); + if (put_user(ent_count, p++)) + return -EFAULT; + + if (get_user(size, p)) + return -EFAULT; + if (put_user(POOLWORDS, p++)) + return -EFAULT; if (size < 0) return -EINVAL; if (size > POOLWORDS) @@ -1467,16 +1461,12 @@ if (!capable(CAP_SYS_ADMIN)) return -EPERM; p = (int *) arg; - retval = verify_area(VERIFY_READ, (void *) p, 2*sizeof(int)); - if (retval) - return(retval); - get_user(ent_count, p++); + if (get_user(ent_count, p++)) + return -EFAULT; if (ent_count < 0) return -EINVAL; - get_user(size, p++); - retval = verify_area(VERIFY_READ, (void *) p, size); - if (retval) - return retval; + if (get_user(size, p++)) + return -EFAULT; retval = random_write(file, (const char *) p, size, &file->f_pos); if (retval < 0) diff -u --recursive --new-file v2.1.128/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.1.128/linux/drivers/char/vt.c Mon Sep 28 10:51:33 1998 +++ linux/drivers/char/vt.c Sun Nov 15 11:24:14 1998 @@ -57,6 +57,11 @@ 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 @@ /* * this is naive. */ - ucval = KB_101; + ucval = keyboard_type; goto setchar; #ifndef __alpha__ diff -u --recursive --new-file v2.1.128/linux/drivers/macintosh/Makefile linux/drivers/macintosh/Makefile --- v2.1.128/linux/drivers/macintosh/Makefile Thu Aug 6 14:06:32 1998 +++ linux/drivers/macintosh/Makefile Sun Nov 15 10:51:46 1998 @@ -16,14 +16,15 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/macintosh/adb.c linux/drivers/macintosh/adb.c --- v2.1.128/linux/drivers/macintosh/adb.c Wed Aug 26 11:37:38 1998 +++ linux/drivers/macintosh/adb.c Sun Nov 15 10:51:46 1998 @@ -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 @@ } #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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/macintosh/mac_keyb.c linux/drivers/macintosh/mac_keyb.c --- v2.1.128/linux/drivers/macintosh/mac_keyb.c Thu Aug 6 14:06:32 1998 +++ linux/drivers/macintosh/mac_keyb.c Sun Nov 15 10:51:46 1998 @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -170,16 +172,22 @@ 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 @@ 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 @@ * 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 }; + static unsigned 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); + 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 @@ 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,33 +397,6 @@ */ /* - 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 - 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. @@ -433,28 +404,27 @@ 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. + 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. - NOTE: data[0] is confirmed by the parent function and need not be - checked here. + For Apple's 3-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 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. */ 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 @@ 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 @@ /* 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 @@ /* 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 @@ 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 */ @@ -633,10 +607,4 @@ ADB_WRITEREG(mouse_ids.id[i],1), 03,0x38); } } -} - -void adb_setup_mouse( char *s, int *ints ) -{ - if (ints[0] >= 1) - adb_emulate_buttons = ints[1]; } diff -u --recursive --new-file v2.1.128/linux/drivers/macintosh/macio-adb.c linux/drivers/macintosh/macio-adb.c --- v2.1.128/linux/drivers/macintosh/macio-adb.c Fri May 8 23:14:47 1998 +++ linux/drivers/macintosh/macio-adb.c Sun Nov 15 10:51:46 1998 @@ -61,8 +61,9 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c --- v2.1.128/linux/drivers/macintosh/macserial.c Sun Nov 8 14:02:58 1998 +++ linux/drivers/macintosh/macserial.c Sun Nov 15 10:51:47 1998 @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef CONFIG_KGDB #include #endif @@ -85,7 +86,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE| ZILOG_CLOSING); wake_up_interruptible(&info->close_wait); + restore_flags(flags); } @@ -1508,9 +1534,25 @@ /* * 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/macintosh/macserial.h linux/drivers/macintosh/macserial.h --- v2.1.128/linux/drivers/macintosh/macserial.h Sat Aug 16 09:53:08 1997 +++ linux/drivers/macintosh/macserial.h Sun Nov 15 10:51:47 1998 @@ -84,6 +84,7 @@ struct mac_zschannel { volatile unsigned char *control; volatile unsigned char *data; + spinlock_t lock; }; struct mac_serial { @@ -91,11 +92,13 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/macintosh/mediabay.c linux/drivers/macintosh/mediabay.c --- v2.1.128/linux/drivers/macintosh/mediabay.c Sun Nov 8 14:02:59 1998 +++ linux/drivers/macintosh/mediabay.c Sun Nov 15 10:51:47 1998 @@ -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 @@ * 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 @@ media_bay_init(void) { struct device_node *np; - - np = find_devices("media-bay"); - if (np == NULL || np->n_addrs == 0) - return; - mb_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); + int n,i; + + for (i=0; in_addrs == 0) + continue; + media_bays[n].addr = (volatile struct media_bay_hw *) + ioremap(np->addrs[0].address, sizeof(struct media_bay_hw)); + +#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 @@ #endif int -check_media_bay(int what) +check_media_bay(struct device_node *which_bay, int what) { - return what == media_bay_id && mb_ready; +#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 -u --recursive --new-file v2.1.128/linux/drivers/macintosh/via-cuda.c linux/drivers/macintosh/via-cuda.c --- v2.1.128/linux/drivers/macintosh/via-cuda.c Sun Jun 7 11:16:31 1998 +++ linux/drivers/macintosh/via-cuda.c Sun Nov 15 10:51:47 1998 @@ -80,7 +80,8 @@ 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 @@ /* 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 @@ /* 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 -u --recursive --new-file v2.1.128/linux/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c --- v2.1.128/linux/drivers/macintosh/via-pmu.c Wed Aug 26 11:37:38 1998 +++ linux/drivers/macintosh/via-pmu.c Sun Nov 15 10:51:47 1998 @@ -30,6 +30,7 @@ #include #include #include +#include /* Misc minor number allocated for /dev/pmu */ #define PMU_MINOR 154 @@ -99,7 +100,8 @@ 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 @@ 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 @@ /* 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 @@ /* 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 @@ 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 @@ 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 @@ { } +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,11 +945,13 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/misc/parport_arc.c linux/drivers/misc/parport_arc.c --- v2.1.128/linux/drivers/misc/parport_arc.c Fri Oct 23 22:01:21 1998 +++ linux/drivers/misc/parport_arc.c Sun Nov 15 09:52:25 1998 @@ -14,6 +14,7 @@ * a subset of the standard printer control lines connected. */ +#include #include #include #include @@ -141,7 +142,9 @@ printk(KERN_INFO "%s: Archimedes on-board port, using irq %d\n", p->irq); +#ifdef CONFIG_PROC_FS parport_proc_register(p); +#endif p->flags |= PARPORT_FLAG_COMA; if (parport_probe_hook) diff -u --recursive --new-file v2.1.128/linux/drivers/misc/parport_ax.c linux/drivers/misc/parport_ax.c --- v2.1.128/linux/drivers/misc/parport_ax.c Fri Oct 23 22:01:21 1998 +++ linux/drivers/misc/parport_ax.c Sun Nov 15 09:52:26 1998 @@ -11,6 +11,7 @@ * Grant Guenther */ +#include #include #include #include @@ -585,7 +586,9 @@ printmode(ECPPS2); } printk("]\n"); +#ifdef CONFIG_PROC_FS parport_proc_register(p); +#endif p->flags |= PARPORT_FLAG_COMA; p->ops->write_control(p, 0x0c); @@ -628,7 +631,9 @@ if (p->modes & PARPORT_MODE_PCSPP) { if (!(p->flags & PARPORT_FLAG_COMA)) parport_quiesce(p); +#ifdef CONFIG_PROC_FS parport_proc_unregister(p); +#endif parport_unregister_port(p); } p = tmp; diff -u --recursive --new-file v2.1.128/linux/drivers/misc/parport_init.c linux/drivers/misc/parport_init.c --- v2.1.128/linux/drivers/misc/parport_init.c Tue Apr 14 14:29:20 1998 +++ linux/drivers/misc/parport_init.c Fri Nov 13 10:29:44 1998 @@ -98,13 +98,17 @@ #ifdef MODULE int init_module(void) { +#ifdef CONFIG_PROC_FS (void)parport_proc_init(); /* We can go on without it. */ +#endif return 0; } void cleanup_module(void) { +#ifdef CONFIG_PROC_FS parport_proc_cleanup(); +#endif } #else __initfunc(int parport_init(void)) @@ -115,7 +119,9 @@ #ifdef CONFIG_PNP_PARPORT parport_probe_hook = &parport_probe_one; #endif +#ifdef CONFIG_PROC_FS parport_proc_init(); +#endif #ifdef CONFIG_PARPORT_PC parport_pc_init(io, irq, dma); #endif @@ -139,8 +145,10 @@ EXPORT_SYMBOL(parport_enumerate); EXPORT_SYMBOL(parport_ieee1284_nibble_mode_ok); EXPORT_SYMBOL(parport_wait_peripheral); +#ifdef CONFIG_PROC_FS EXPORT_SYMBOL(parport_proc_register); EXPORT_SYMBOL(parport_proc_unregister); +#endif EXPORT_SYMBOL(parport_probe_hook); EXPORT_SYMBOL(parport_parse_irqs); diff -u --recursive --new-file v2.1.128/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c --- v2.1.128/linux/drivers/misc/parport_pc.c Sun Nov 8 14:02:59 1998 +++ linux/drivers/misc/parport_pc.c Sun Nov 15 09:52:26 1998 @@ -34,6 +34,7 @@ * accomodate this. */ +#include #include #include #include @@ -755,9 +756,11 @@ } #undef printmode printk("]\n"); +#ifdef CONFIG_PROC_FS if (probedirq != PARPORT_IRQ_NONE) printk("%s: detected irq %d; use procfs to enable interrupt-driven operation.\n", p->name, probedirq); parport_proc_register(p); +#endif p->flags |= PARPORT_FLAG_COMA; /* Done probing. Now put the port into a sensible start-up state. */ @@ -821,7 +824,9 @@ if (p->modes & PARPORT_MODE_PCSPP) { if (!(p->flags & PARPORT_FLAG_COMA)) parport_quiesce(p); +#ifdef CONFIG_PROC_FS parport_proc_unregister(p); +#endif parport_unregister_port(p); } p = tmp; diff -u --recursive --new-file v2.1.128/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c --- v2.1.128/linux/drivers/net/3c59x.c Thu Nov 12 16:21:19 1998 +++ linux/drivers/net/3c59x.c Fri Nov 13 10:29:44 1998 @@ -77,7 +77,6 @@ #include #include #include -#include #include #include diff -u --recursive --new-file v2.1.128/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.1.128/linux/drivers/net/Space.c Thu Nov 12 16:21:19 1998 +++ linux/drivers/net/Space.c Fri Nov 13 10:29:43 1998 @@ -559,7 +559,7 @@ #if defined(CONFIG_LTPC) extern int ltpc_probe(struct device *); static struct device dev_ltpc = { - "ltalk0\0 ", + "lt0\0 ", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NEXT_DEV, ltpc_probe }; diff -u --recursive --new-file v2.1.128/linux/drivers/net/at1700.c linux/drivers/net/at1700.c --- v2.1.128/linux/drivers/net/at1700.c Thu Nov 12 16:21:19 1998 +++ linux/drivers/net/at1700.c Sun Nov 15 09:52:26 1998 @@ -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 -u --recursive --new-file v2.1.128/linux/drivers/net/bmac.c linux/drivers/net/bmac.c --- v2.1.128/linux/drivers/net/bmac.c Sun Nov 8 14:02:59 1998 +++ linux/drivers/net/bmac.c Sun Nov 15 10:51:47 1998 @@ -54,6 +54,7 @@ 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 @@ 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 @@ //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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/net/hamradio/mkiss.c linux/drivers/net/hamradio/mkiss.c --- v2.1.128/linux/drivers/net/hamradio/mkiss.c Sun Jul 26 11:57:16 1998 +++ linux/drivers/net/hamradio/mkiss.c Fri Nov 13 10:29:44 1998 @@ -894,7 +894,6 @@ static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) { struct ax_disp *ax = (struct ax_disp *)tty->disc_data; - int err; unsigned int tmp; /* First make sure we're connected. */ diff -u --recursive --new-file v2.1.128/linux/drivers/net/hostess_sv11.c linux/drivers/net/hostess_sv11.c --- v2.1.128/linux/drivers/net/hostess_sv11.c Fri Oct 23 22:01:21 1998 +++ linux/drivers/net/hostess_sv11.c Fri Nov 13 10:29:44 1998 @@ -160,8 +160,8 @@ static int hostess_ioctl(struct device *d, struct ifreq *ifr, int cmd) { - struct sv11_device *sv11=d->priv; - /* z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ + /* struct sv11_device *sv11=d->priv; + z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ return sppp_do_ioctl(d, ifr,cmd); } diff -u --recursive --new-file v2.1.128/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c --- v2.1.128/linux/drivers/net/ltpc.c Fri Oct 23 22:01:21 1998 +++ linux/drivers/net/ltpc.c Fri Nov 13 10:29:43 1998 @@ -67,6 +67,25 @@ * Hacked about a bit to clean things up - Alan Cox * Probably broken it from the origina 1.8 * + + * 1998/11/09: David Huggins-Daines + * Cleaned up the initialization code to use the standard autoirq methods, + and to probe for things in the standard order of i/o, irq, dma. This + removes the "reset the reset" hack, because I couldn't figure out an + easy way to get the card to trigger an interrupt after it. + * Added support for passing configuration parameters on the kernel command + line and through insmod + * Changed the device name from "ltalk0" to "lt0", both to conform with the + other localtalk driver, and to clear up the inconsistency between the + module and the non-module versions of the driver :-) + * Added a bunch of comments (I was going to make some enums for the state + codes and the register offsets, but I'm still not sure exactly what their + semantics are) + * Don't poll anymore in interrupt-driven mode + * It seems to work as a module now (as of 2.1.127), but I don't think + I'm responsible for that... + + * * Revision 1.7 1996/12/12 03:42:33 bradford * DMA alloc cribbed from 3c505.c. * @@ -180,6 +199,9 @@ #define DEBUG_UPPER 2 #define DEBUG_LOWER 4 +static int io=0; +static int irq=0; +static int dma=0; #ifdef MODULE #include @@ -245,25 +267,34 @@ return __get_dma_pages(GFP_KERNEL, order); } +/* DMA data buffer, DMA command buffer */ static unsigned char *ltdmabuf; static unsigned char *ltdmacbuf; +/* private struct, holds our appletalk address */ + struct ltpc_private { struct net_device_stats stats; struct at_addr my_addr; }; +/* transmit queue element struct */ + struct xmitQel { struct xmitQel *next; + /* command buffer */ unsigned char *cbuf; short cbuflen; + /* data buffer */ unsigned char *dbuf; short dbuflen; unsigned char QWrite; /* read or write data */ unsigned char mailbox; }; +/* the transmit queue itself */ + static struct xmitQel *xmQhd=NULL,*xmQtl=NULL; static void enQ(struct xmitQel *qel) @@ -310,8 +341,10 @@ return qel; } +/* and... the queue elements we'll be using */ static struct xmitQel qels[16]; +/* and their corresponding mailboxes */ static unsigned char mailbox[16]; static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; @@ -331,6 +364,8 @@ return 1; /* timed out */ } +/* get the first free mailbox */ + static int getmbox(void) { unsigned long flags; @@ -347,6 +382,7 @@ return 0; } +/* read a command from the card */ static void handlefc(struct device *dev) { /* called *only* from idle, non-reentrant */ @@ -370,6 +406,7 @@ if ( wait_timeout(dev,0xfc) ) printk("timed out in handlefc\n"); } +/* read data from the card */ static void handlefd(struct device *dev) { int dma = dev->dma; @@ -463,7 +500,8 @@ if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n"); } -static unsigned char rescbuf[2] = {0,0}; +/* ready made command for getting the result from the card */ +static unsigned char rescbuf[2] = {LT_GETRESULT,0}; static unsigned char resdbuf[2]; static int QInIdle=0; @@ -482,7 +520,7 @@ struct xmitQel *q=0; int oops; int i; - int statusPort = dev->base_addr+6; + int base = dev->base_addr; save_flags(flags); cli(); @@ -495,8 +533,8 @@ restore_flags(flags); - - (void) inb_p(statusPort); /* this tri-states the IRQ line */ + /* this tri-states the IRQ line */ + (void) inb_p(base+6); oops = 100; @@ -506,19 +544,22 @@ goto done; } - state = inb_p(statusPort); - if (state != inb_p(statusPort)) goto loop; + state = inb_p(base+6); + if (state != inb_p(base+6)) goto loop; switch(state) { - case 0xfc: + case 0xfc: + /* incoming command */ if (debug&DEBUG_LOWER) printk("idle: fc\n"); handlefc(dev); break; - case 0xfd: + case 0xfd: + /* incoming data */ if(debug&DEBUG_LOWER) printk("idle: fd\n"); handlefd(dev); break; - case 0xf9: + case 0xf9: + /* result ready */ if (debug&DEBUG_LOWER) printk("idle: f9\n"); if(!mboxinuse[0]) { mboxinuse[0] = 1; @@ -536,6 +577,7 @@ printk("timed out idle f9\n"); break; case 0xf8: + /* ?? */ if (xmQhd) { inb_p(dev->base_addr+1); inb_p(dev->base_addr+0); @@ -545,7 +587,8 @@ goto done; } break; - case 0xfa: + case 0xfa: + /* waiting for command */ if(debug&DEBUG_LOWER) printk("idle: fa\n"); if (xmQhd) { q=deQ(); @@ -561,7 +604,7 @@ printk("\n"); } handlecommand(dev); - if(0xfa==inb_p(statusPort)) { + if(0xfa==inb_p(base+6)) { /* we timed out, so return */ goto done; } @@ -582,13 +625,17 @@ } } break; - case 0xfb: + case 0Xfb: + /* data transfer ready */ if(debug&DEBUG_LOWER) printk("idle: fb\n"); if(q->QWrite) { memcpy(ltdmabuf,q->dbuf,q->dbuflen); handlewrite(dev); } else { handleread(dev); + /* non-zero mailbox numbers are for + commmands, 0 is for GETRESULT + requests */ if(q->mailbox) { memcpy(q->dbuf,ltdmabuf,q->dbuflen); } else { @@ -605,13 +652,14 @@ QInIdle=0; /* now set the interrupts back as appropriate */ - /* the first 7 takes it out of tri-state (but still high) */ + /* the first read takes it out of tri-state (but still high) */ /* the second resets it */ - /* note that after this point, any read of 6 will trigger an interrupt */ + /* note that after this point, any read of base+6 will + trigger an interrupt */ if (dev->irq) { - inb_p(dev->base_addr+7); - inb_p(dev->base_addr+7); + inb_p(base+7); + inb_p(base+7); } return; } @@ -703,6 +751,8 @@ return do_write(dev, &c, sizeof(c.setflags),&c,0); } +/* LLAP to DDP translation */ + static int sendup_buffer (struct device *dev) { /* on entry, command is in ltdmacbuf, data in ltdmabuf */ @@ -912,23 +962,14 @@ if (!dev) return; /* we've been downed */ - if (dev->irq) - { - /* we're set up for interrupts */ - if (0xf8 != inb_p(dev->base_addr+7)) { - /* trigger an interrupt */ - (void) inb_p(dev->base_addr+6); - } - ltpc_timer.expires = jiffies+100; - } else { - /* we're strictly polling mode */ - idle(dev); - ltpc_timer.expires = jiffies+5; - } - + idle(dev); + ltpc_timer.expires = jiffies+5; + add_timer(<pc_timer); } +/* DDP to LLAP translation */ + static int ltpc_xmit(struct sk_buff *skb, struct device *dev) { /* in kernel 1.3.xx, on entry skb->data points to ddp header, @@ -975,150 +1016,18 @@ return stats; } -static unsigned short irqhitmask; - -__initfunc(static void lt_probe_handler(int irq, void *dev_id, struct pt_regs *reg_ptr)) -{ - irqhitmask |= 1<jiffies) ; /* wait for strays */ - - straymask = irqhitmask; /* pick up any strays */ - - /* if someone already owns this address, don't probe */ - if (!check_region(0x220,8)) { - inb_p(0x227); - inb_p(0x227); - x=inb_p(0x226); - timeout = jiffies+2; - while(timeout>jiffies) ; - if(straymask != irqhitmask) base = 0x220; - } - if (!check_region(0x240,8)) { - inb_p(0x247); - inb_p(0x247); - y=inb_p(0x246); - timeout = jiffies+2; - while(timeout>jiffies) ; - if(straymask != irqhitmask) base = 0x240; - } - - /* at this point, either we have an irq and the base addr, or - * there isn't any irq and we don't know the base address, but - * in either event the card is no longer latched in reset and - * the irq request line is tri-stated. - */ - - cli(); - - if (!probe3) free_irq(3,dev); - if (!probe4) free_irq(4,dev); - if (!probe9) free_irq(9,dev); - - sti(); - - irqhitmask &= ~straymask; - - irq = ffz(~irqhitmask); - if (irqhitmask != 1<=0xf0) ) base = 0x220; - } - - if (!check_region(0x240,8)) { - y = inb_p(0x240+6); - if ( (y!=0xff) && (y>=0xf0) ) base = 0x240; - } - } - - if(base) { - request_region(base,8,"ltpc"); - } else { - printk("LocalTalk card not found; 220 = %02x, 240 = %02x.\n",x,y); - restore_flags(flags); - return -1; - } - - ltdmabuf = (unsigned char *) dma_mem_alloc(1000); - - if (ltdmabuf) ltdmacbuf = <dmabuf[800]; - - if (!ltdmabuf) { - printk("ltpc: mem alloc failed\n"); - restore_flags(flags); - return(-1); - } - - if(debug&DEBUG_VERBOSE) { - printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); - } - - /* reset the card */ - - inb_p(base+1); - inb_p(base+3); - timeout = jiffies+2; - while(timeout>jiffies) ; /* hold it in reset for a coupla jiffies */ - inb_p(base+0); - inb_p(base+2); - inb_p(base+7); /* clear reset */ - inb_p(base+4); - inb_p(base+5); - inb_p(base+5); /* enable dma */ - inb_p(base+6); /* tri-state interrupt line */ - - timeout = jiffies+100; - - while(timeout>jiffies) { - /* wait for the card to complete initialization */ - } - - /* now, figure out which dma channel we're using */ - - /* set up both dma 1 and 3 for read call */ - - if (!request_dma(1,"ltpc")) { - - f=claim_dma_lock(); - disable_dma(1); - clear_dma_ff(1); + int dma = 0; + int timeout; + unsigned long f; + + if (!request_dma(1,"ltpc")) { + f=claim_dma_lock(); + disable_dma(1); + clear_dma_ff(1); set_dma_mode(1,DMA_MODE_WRITE); set_dma_addr(1,virt_to_bus(ltdmabuf)); set_dma_count(1,sizeof(struct lt_mem)); @@ -1142,26 +1051,26 @@ /* FIXME -- do timings better! */ - ltdmabuf[0] = 2; /* read request */ + ltdmabuf[0] = LT_READMEM; ltdmabuf[1] = 1; /* mailbox */ ltdmabuf[2] = 0; ltdmabuf[3] = 0; /* address */ ltdmabuf[4] = 0; ltdmabuf[5] = 1; /* read 0x0100 bytes */ ltdmabuf[6] = 0; /* dunno if this is necessary */ - inb_p(base+1); - inb_p(base+0); + inb_p(io+1); + inb_p(io+0); timeout = jiffies+100; while(timeout>jiffies) { - if ( 0xfa == inb_p(base+6) ) break; + if ( 0xfa == inb_p(io+6) ) break; } - inb_p(base+3); - inb_p(base+2); + inb_p(io+3); + inb_p(io+2); while(timeout>jiffies) { - if ( 0xfb == inb_p(base+6) ) break; + if ( 0xfb == inb_p(io+6) ) break; } - /* release the other dma channel */ + /* release the other dma channel (if we opened both of them) */ if ( (dma&0x2) && (get_dma_residue(3)==sizeof(struct lt_mem)) ){ dma&=1; @@ -1172,31 +1081,134 @@ dma&=0x2; free_dma(1); } - - if (!dma) { /* no dma channel */ - printk("No DMA channel found on ltpc card.\n"); - restore_flags(flags); - return -1; - } - + /* fix up dma number */ dma|=1; - /* set up read */ + return dma; +} + +__initfunc(int ltpc_probe(struct device *dev)) +{ + int err; + int x=0,y=0; + int timeout; + int autoirq; + unsigned long flags; + unsigned long f; + + save_flags(flags); + + /* probe for the I/O port address */ + if (io != 0x240 && !check_region(0x220,8)) { + x = inb_p(0x220+6); + if ( (x!=0xff) && (x>=0xf0) ) io = 0x220; + } + + if (io != 0x220 && !check_region(0x240,8)) { + y = inb_p(0x240+6); + if ( (y!=0xff) && (y>=0xf0) ) io = 0x240; + } + + if(io) { + /* found it, now grab it */ + request_region(io,8,"ltpc"); + } else { + /* give up in despair */ + printk ("LocalTalk card not found; 220 = %02x, 240 = %02x.\n", + x,y); + restore_flags(flags); + return -1; + } + + /* probe for the IRQ line */ + if (irq < 2) { + autoirq_setup(2); + + /* reset the interrupt line */ + inb_p(io+7); + inb_p(io+7); + /* trigger an interrupt (I hope) */ + inb_p(io+6); + + autoirq = autoirq_report(1); + + if (autoirq == 0) { + printk("ltpc: probe at %#x failed to detect IRQ line.\n", + io); + } + else { + irq = autoirq; + } + } + + /* allocate a DMA buffer */ + ltdmabuf = (unsigned char *) dma_mem_alloc(1000); + + if (ltdmabuf) ltdmacbuf = <dmabuf[800]; + + if (!ltdmabuf) { + printk("ltpc: mem alloc failed\n"); + restore_flags(flags); + return(-1); + } + + if(debug&DEBUG_VERBOSE) { + printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); + } + + /* reset the card */ + + inb_p(io+1); + inb_p(io+3); + timeout = jiffies+2; + while(timeout>jiffies) ; /* hold it in reset for a coupla jiffies */ + inb_p(io+0); + inb_p(io+2); + inb_p(io+7); /* clear reset */ + inb_p(io+4); + inb_p(io+5); + inb_p(io+5); /* enable dma */ + inb_p(io+6); /* tri-state interrupt line */ + + timeout = jiffies+100; + + while(timeout>jiffies) { + /* wait for the card to complete initialization */ + } + + /* now, figure out which dma channel we're using, unless it's + already been specified */ + /* well, 0 is a legal DMA channel, but the LTPC card doesn't + use it... */ + if (dma == 0) { + dma = ltpc_probe_dma(io); + if (!dma) { /* no dma channel */ + printk("No DMA channel found on ltpc card.\n"); + restore_flags(flags); + return -1; + } + } + + /* print out friendly message */ if(irq) - printk("LocalTalk card found at %03x, IR%d, DMA%d.\n",base,irq,dma); + printk("Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma); else - printk("LocalTalk card found at %03x, DMA%d. Using polled mode.\n",base,dma); - - dev->base_addr = base; + printk("Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); + + /* seems more logical to do this *after* probing the card... */ + err = ltpc_init(dev); + if (err) return err; + + dev->base_addr = io; dev->irq = irq; dev->dma = dma; - if(debug&DEBUG_VERBOSE) { - printk("finishing up transfer\n"); - } - + /* the card will want to send a result at this point */ + /* (I think... leaving out this part makes the kernel crash, + so I put it back in...) */ + f=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); @@ -1206,41 +1218,65 @@ enable_dma(dma); release_dma_lock(f); - (void) inb_p(base+3); - (void) inb_p(base+2); + (void) inb_p(io+3); + (void) inb_p(io+2); timeout = jiffies+100; while(timeout>jiffies) { - if( 0xf9 == inb_p(base+6)) break; + if( 0xf9 == inb_p(io+6)) break; } if(debug&DEBUG_VERBOSE) { printk("setting up timer and irq\n"); } - init_timer(<pc_timer); - ltpc_timer.function=ltpc_poll; - ltpc_timer.data = (unsigned long) dev; - if (irq) { + /* grab it and don't let go :-) */ (void) request_irq( irq, <pc_interrupt, 0, "ltpc", dev); - (void) inb_p(base+7); /* enable interrupts from board */ - (void) inb_p(base+7); /* and reset irq line */ - ltpc_timer.expires = 100; - /* poll it once per second just in case */ + (void) inb_p(io+7); /* enable interrupts from board */ + (void) inb_p(io+7); /* and reset irq line */ } else { - ltpc_timer.expires = 5; - /* polled mode -- 20 times per second */ - } - - ltpc_timer.expires += jiffies; /* 1.2 to 1.3 change... */ + /* polled mode -- 20 times per second */ + /* this is really, really slow... should it poll more often? */ + init_timer(<pc_timer); + ltpc_timer.function=ltpc_poll; + ltpc_timer.data = (unsigned long) dev; - add_timer(<pc_timer); - - restore_flags(flags); + ltpc_timer.expires = jiffies + 5; + add_timer(<pc_timer); + restore_flags(flags); + } return 0; } +/* handles "ltpc=io,irq,dma" kernel command lines */ +__initfunc(void ltpc_setup(char *str, int *ints)) +{ + if (ints[0] == 0) { + if (str && !strncmp(str, "auto", 4)) { + /* do nothing :-) */ + } + else { + /* usage message */ + printk (KERN_ERR + "ltpc: usage: ltpc=auto|iobase[,irq[,dma]]\n"); + } + return; + } else { + io = ints[1]; + if (ints[0] > 1) { + irq = ints[2]; + return; + } + if (ints[0] > 2) { + dma = ints[3]; + return; + } + /* ignore any other paramters */ + } + return; +} + #ifdef MODULE static char dev_name[8]; @@ -1251,17 +1287,28 @@ 0x0, 0, 0, 0, 0, NULL, ltpc_probe }; +MODULE_PARM(debug, "i"); +MODULE_PARM(io, "i"); +MODULE_PARM(irq, "i"); +MODULE_PARM(dma, "i"); + int init_module(void) { + int err, result; + + if(io == 0) + printk(KERN_NOTICE + "ltpc: Autoprobing is not recommended for modules\n"); + /* Find a name for this unit */ - int err=dev_alloc_name(&dev_ltpc,"lt%d"); + err=dev_alloc_name(&dev_ltpc,"lt%d"); if(err<0) return err; - if (register_netdev(&dev_ltpc) != 0) { - if(debug&DEBUG_VERBOSE) printk("EIO from register_netdev\n"); - return -EIO; + if ((result = register_netdev(&dev_ltpc)) != 0) { + printk(KERN_DEBUG "could not register Localtalk-PC device\n"); + return result; } else { if(debug&DEBUG_VERBOSE) printk("0 from register_netdev\n"); return 0; @@ -1322,3 +1369,4 @@ if(debug&DEBUG_VERBOSE) printk("returning from cleanup_module\n"); } #endif /* MODULE */ + diff -u --recursive --new-file v2.1.128/linux/drivers/net/rtl8139.c linux/drivers/net/rtl8139.c --- v2.1.128/linux/drivers/net/rtl8139.c Thu Nov 12 16:21:19 1998 +++ linux/drivers/net/rtl8139.c Sun Nov 15 09:52:26 1998 @@ -56,7 +56,6 @@ /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (4*HZ) -#include #ifdef MODULE #ifdef MODVERSIONS #include diff -u --recursive --new-file v2.1.128/linux/drivers/net/shaper.c linux/drivers/net/shaper.c --- v2.1.128/linux/drivers/net/shaper.c Tue Aug 18 22:02:04 1998 +++ linux/drivers/net/shaper.c Fri Nov 13 10:29:44 1998 @@ -157,7 +157,7 @@ skb->shapelatency=0; skb->shapeclock=shaper->recovery; - if(skb->shapeclockshapeclock, jiffies)) skb->shapeclock=jiffies; skb->priority=0; /* short term bug fix */ skb->shapestamp=jiffies; @@ -320,7 +320,7 @@ if(sh_debug) printk("Clock = %d, jiffies = %ld\n", skb->shapeclock, jiffies); - if(skb->shapeclock <= jiffies + SHAPER_BURST) + if(skb->shapeclock - jiffies <= SHAPER_BURST) { /* * Pull the frame and get interrupts back on. @@ -385,10 +385,14 @@ /* * Can't open until attached. + * Also can't open until speed is set, or we'll get + * a division by zero. */ if(shaper->dev==NULL) return -ENODEV; + if(shaper->bitspersec==0) + return -EINVAL; MOD_INC_USE_COUNT; return 0; } @@ -543,6 +547,7 @@ shdev->type=dev->type; shdev->addr_len=dev->addr_len; shdev->mtu=dev->mtu; + sh->bitspersec=0; return 0; } @@ -564,7 +569,7 @@ case SHAPER_GET_DEV: if(sh->dev==NULL) return -ENODEV; - memcpy(ss->ss_name, sh->dev->name, sizeof(ss->ss_name)); + strcpy(ss->ss_name, sh->dev->name); return 0; case SHAPER_SET_SPEED: shaper_setspeed(sh,ss->ss_speed); diff -u --recursive --new-file v2.1.128/linux/drivers/net/syncppp.c linux/drivers/net/syncppp.c --- v2.1.128/linux/drivers/net/syncppp.c Fri Oct 23 22:01:21 1998 +++ linux/drivers/net/syncppp.c Fri Nov 13 10:29:44 1998 @@ -859,6 +859,9 @@ if(dev->flags&IFF_UP) return -EBUSY; + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + switch(cmd) { case SPPPIOCCISCO: @@ -872,11 +875,7 @@ case SPPPIOCDEBUG: sp->pp_flags&=~PP_DEBUG; if(ifr->ifr_flags) - { - if(!capable(CAP_NET_ADMIN)) - return -EPERM; sp->pp_flags|=PP_DEBUG; - } break; default: return -EINVAL; diff -u --recursive --new-file v2.1.128/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c --- v2.1.128/linux/drivers/net/yellowfin.c Thu Nov 12 16:21:20 1998 +++ linux/drivers/net/yellowfin.c Sun Nov 15 09:52:26 1998 @@ -63,7 +63,6 @@ /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT ((2000*HZ)/1000) -#include #ifdef MODULE #ifdef MODVERSIONS #include diff -u --recursive --new-file v2.1.128/linux/drivers/pci/pcisyms.c linux/drivers/pci/pcisyms.c --- v2.1.128/linux/drivers/pci/pcisyms.c Thu Nov 12 16:21:20 1998 +++ linux/drivers/pci/pcisyms.c Sun Nov 15 09:52:26 1998 @@ -6,6 +6,7 @@ * Copyright 1998 Martin Mares */ +#include #include #include diff -u --recursive --new-file v2.1.128/linux/drivers/scsi/ChangeLog.ncr53c8xx linux/drivers/scsi/ChangeLog.ncr53c8xx --- v2.1.128/linux/drivers/scsi/ChangeLog.ncr53c8xx Sun Nov 8 14:03:02 1998 +++ linux/drivers/scsi/ChangeLog.ncr53c8xx Sun Nov 15 09:57:00 1998 @@ -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 -u --recursive --new-file v2.1.128/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in --- v2.1.128/linux/drivers/scsi/Config.in Thu Nov 12 16:21:20 1998 +++ linux/drivers/scsi/Config.in Sun Nov 15 09:57:00 1998 @@ -80,7 +80,7 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c --- v2.1.128/linux/drivers/scsi/NCR5380.c Wed Sep 9 14:51:08 1998 +++ linux/drivers/scsi/NCR5380.c Fri Nov 13 10:29:44 1998 @@ -686,7 +686,7 @@ save_flags(flags); cli(); for (; expires_first && - ((struct NCR5380_hostdata *)expires_first->hostdata)->time_expires <= jiffies; ) + time_before_eq(((struct NCR5380_hostdata *)expires_first->hostdata)->time_expires, jiffies); ) { instance = ((struct NCR5380_hostdata *) expires_first->hostdata)->next_timer; ((struct NCR5380_hostdata *) expires_first->hostdata)->next_timer = NULL; @@ -776,7 +776,7 @@ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); - while (probe_irq == IRQ_NONE && jiffies < timeout) + while (probe_irq == IRQ_NONE && time_before(jiffies,timeout)) barrier(); NCR5380_write(SELECT_ENABLE_REG, 0); @@ -1123,7 +1123,7 @@ printk("scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no); timeout = jiffies + 5 * HZ; - while (jiffies < timeout && (NCR5380_read(STATUS_REG) & SR_BSY)); + while (time_before(jiffies,timeout) && (NCR5380_read(STATUS_REG) & SR_BSY)); break; case 2: printk("scsi%d: bus busy, attempting abort\n", @@ -1417,7 +1417,7 @@ && !hostdata->dmalen #endif #ifdef USLEEP - && (!hostdata->time_expires || hostdata->time_expires <= jiffies) + && (!hostdata->time_expires || time_before_eq(hostdata->time_expires, jiffies)) #endif ) { restore_flags(flags); @@ -1532,10 +1532,10 @@ spin_unlock_irq(&io_request_lock); while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK - && jiffies < timeout); + && time_before(jiffies, timeout)); spin_lock_irq(&io_request_lock); - if (jiffies >= timeout) + if (time_after_eq(jiffies, timeout) ) printk("scsi%d: timeout at NCR5380.c:%d\n", host->host_no, __LINE__); } @@ -1681,11 +1681,11 @@ spin_unlock_irq(&io_request_lock); while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) - && jiffies < timeout); + && time_before(jiffies,timeout)); spin_lock_irq(&io_request_lock); - if (jiffies >= timeout) { + if (time_after_eq(jiffies,timeout)) { printk("scsi: arbitration timeout at %d\n", __LINE__); NCR5380_write(MODE_REG, MR_BASE); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); @@ -1844,7 +1844,7 @@ waiting period */ #else spin_unlock_irq(&io_request_lock); - while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) & + while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO))); spin_lock_irq(&io_request_lock); #endif @@ -1915,10 +1915,10 @@ unsigned long timeout = jiffies + NCR_TIMEOUT; spin_unlock_irq(&io_request_lock); - while (!(NCR5380_read(STATUS_REG) & SR_REQ) && jiffies < timeout); + while (!(NCR5380_read(STATUS_REG) & SR_REQ) && time_before(jiffies, timeout)); spin_lock_irq(&io_request_lock); - if (jiffies >= timeout) { + if (time_after_eq(jiffies, timeout)) { printk("scsi%d: timeout at NCR5380.c:%d\n", __LINE__); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); return -1; @@ -3082,7 +3082,7 @@ { /* RvC: go to sleep if polling time expired */ - if (!cmd->device->disconnect && jiffies >= poll_time) + if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) { hostdata->time_expires = jiffies + USLEEP_SLEEP; #if (NDEBUG & NDEBUG_USLEEP) diff -u --recursive --new-file v2.1.128/linux/drivers/scsi/fd_mcs.c linux/drivers/scsi/fd_mcs.c --- v2.1.128/linux/drivers/scsi/fd_mcs.c Thu Nov 12 16:21:21 1998 +++ linux/drivers/scsi/fd_mcs.c Sun Nov 15 09:52:27 1998 @@ -88,7 +88,6 @@ #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.1.128/linux/drivers/scsi/mesh.c linux/drivers/scsi/mesh.c --- v2.1.128/linux/drivers/scsi/mesh.c Thu Aug 6 14:06:33 1998 +++ linux/drivers/scsi/mesh.c Sun Nov 15 10:51:48 1998 @@ -28,6 +28,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -222,6 +223,13 @@ 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_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 @@ *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 @@ 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 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.1.128/linux/drivers/scsi/ncr53c8xx.c Sun Nov 8 14:03:02 1998 +++ linux/drivers/scsi/ncr53c8xx.c Sun Nov 15 09:57:00 1998 @@ -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 @@ #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; } @@ -8208,6 +8208,12 @@ 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. */ if (xpt_que_empty(&lp->free_ccbq)) @@ -10072,19 +10078,20 @@ 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 -u --recursive --new-file v2.1.128/linux/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h --- v2.1.128/linux/drivers/scsi/ncr53c8xx.h Sun Nov 8 14:03:02 1998 +++ linux/drivers/scsi/ncr53c8xx.h Sun Nov 15 09:57:00 1998 @@ -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 -u --recursive --new-file v2.1.128/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.1.128/linux/drivers/scsi/scsi.c Fri Oct 23 22:01:21 1998 +++ linux/drivers/scsi/scsi.c Fri Nov 13 10:16:15 1998 @@ -226,6 +226,7 @@ {"MEDIAVIS","RENO CD-ROMX2A","2.03",BLIST_NOLUN},/*Responds to all lun */ {"MICROP", "4110", "*", BLIST_NOTQ}, /* Buggy Tagged Queuing */ {"NEC","CD-ROM DRIVE:841","1.0", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ +{"PHILIPS", "PCA80SC", "V4-2", BLIST_NOLUN}, /* Responds to all lun */ {"RODIME","RO3000S","2.33", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"SANYO", "CRD-250S", "1.20", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 * for aha152x controller, which causes diff -u --recursive --new-file v2.1.128/linux/drivers/scsi/scsi_proc.c linux/drivers/scsi/scsi_proc.c --- v2.1.128/linux/drivers/scsi/scsi_proc.c Tue Jun 23 10:01:24 1998 +++ linux/drivers/scsi/scsi_proc.c Fri Nov 13 10:16:15 1998 @@ -110,14 +110,29 @@ return(-EBADF); } +static void scsi_proc_fill_inode(struct inode *inode, int fill) +{ +Scsi_Host_Template *shpnt; + +shpnt = scsi_hosts; +while (shpnt && shpnt->proc_dir->low_ino != inode->i_ino) + shpnt = shpnt->next; +if (!shpnt || !shpnt->module) + return; +if (fill) + __MOD_INC_USE_COUNT(shpnt->module); +else + __MOD_DEC_USE_COUNT(shpnt->module); +} + void build_proc_dir_entries(Scsi_Host_Template *tpnt) { struct Scsi_Host *hpnt; - struct scsi_dir *scsi_hba_dir; proc_scsi_register(0, tpnt->proc_dir); - + tpnt->proc_dir->fill_inode = &scsi_proc_fill_inode; + hpnt = scsi_hostlist; while (hpnt) { if (tpnt == hpnt->hostt) { diff -u --recursive --new-file v2.1.128/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c --- v2.1.128/linux/drivers/sound/ad1848.c Thu Nov 12 16:21:21 1998 +++ linux/drivers/sound/ad1848.c Fri Nov 13 10:29:44 1998 @@ -1934,7 +1934,7 @@ if (!share_dma) { - if (irq > 0) + if (devc->irq > 0) /* There is no point in freeing irq, if it wasn't allocated */ free_irq(devc->irq, (void *)devc->dev_no); sound_free_dma(audio_devs[dev]->dmap_out->dma); diff -u --recursive --new-file v2.1.128/linux/drivers/sound/dmasound.c linux/drivers/sound/dmasound.c --- v2.1.128/linux/drivers/sound/dmasound.c Thu Nov 12 16:21:22 1998 +++ linux/drivers/sound/dmasound.c Sun Nov 15 10:51:48 1998 @@ -107,18 +107,17 @@ #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 @@ #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 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 @@ }; #endif /* CONFIG_PMAC_PBOOK */ -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ /*** Some declarations *******************************************************/ @@ -587,7 +588,7 @@ 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_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 @@ 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 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_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 @@ } #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 @@ return stereo? utotal * 4: utotal * 2; } -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ #ifdef CONFIG_ATARI @@ -2191,7 +2192,7 @@ }; #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 @@ 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 @@ } #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC /* * PCI PowerMac, with AWACS and DBDMA. @@ -3226,7 +3227,7 @@ { 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 @@ } #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 @@ }; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC static MACHINE machPMac = { DMASND_AWACS, PMacAlloc, PMacFree, PMacIrqInit, #ifdef MODULE @@ -3683,7 +3715,7 @@ break; #endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC case DMASND_AWACS: switch (cmd) { case SOUND_MIXER_READ_DEVMASK: @@ -3733,12 +3765,18 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { int has_sound = 0; int i; -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC struct device_node *np; #endif @@ -4430,7 +4468,7 @@ } #endif /* __mc68000__ */ -#ifdef CONFIG_PMAC +#ifdef CONFIG_PPC awacs_subframe = 0; np = find_devices("awacs"); if (np == 0) { @@ -4479,6 +4517,13 @@ 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 @@ &awacs_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ } -#endif /* CONFIG_PMAC */ +#endif /* CONFIG_PPC */ if (!has_sound) return; diff -u --recursive --new-file v2.1.128/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v2.1.128/linux/drivers/sound/soundcard.c Thu Nov 12 16:21:22 1998 +++ linux/drivers/sound/soundcard.c Fri Nov 13 10:29:44 1998 @@ -292,11 +292,13 @@ return len; } +#ifdef CONFIG_PROC_FS static struct proc_dir_entry proc_root_sound = { PROC_SOUND, 5, "sound", S_IFREG | S_IRUGO, 1, 0, 0, 0, NULL, sound_proc_get_info }; +#endif #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) @@ -842,8 +844,10 @@ audio_init_devices(); } #endif +#ifdef CONFIG_PROC_FS if (proc_register(&proc_root, &proc_root_sound)) printk(KERN_ERR "sound: registering /proc/sound failed\n"); +#endif } static int sound[20] = { diff -u --recursive --new-file v2.1.128/linux/drivers/video/Config.in linux/drivers/video/Config.in --- v2.1.128/linux/drivers/video/Config.in Fri Oct 23 22:01:22 1998 +++ linux/drivers/video/Config.in Fri Nov 13 10:10:11 1998 @@ -22,6 +22,7 @@ tristate 'Amiga CyberVision support' CONFIG_FB_CYBER if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE + bool 'Amiga CyberVisionPPC support (experimental)' CONFIG_FB_CVPPC tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3 tristate 'Amiga CLgen driver' CONFIG_FB_CLGEN fi @@ -55,6 +56,17 @@ bool 'VESA VGA graphics console' CONFIG_FB_VESA define_bool CONFIG_VIDEO_SELECT y fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_PCI" != "n" ]; then + tristate 'Matrox acceleration' CONFIG_FB_MATROX + if [ "$CONFIG_FB_MATROX" != "n" ]; then + bool ' Millenium I/II support' CONFIG_FB_MATROX_MILLENIUM + bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE + bool ' G100/G200 support' CONFIG_FB_MATROX_G100 + bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD + fi + fi + fi if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then bool 'SBUS and UPA framebuffers' CONFIG_FB_SBUS if [ "$CONFIG_FB_SBUS" != "n" ]; then @@ -141,8 +153,9 @@ "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \ + "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ - "$CONFIG_FB_IGA" = "y" ]; then + "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" ]; then define_bool CONFIG_FBCON_CFB8 y else if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ @@ -152,8 +165,9 @@ "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \ + "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ - "$CONFIG_FB_IGA" = "y" ]; then + "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" ]; then define_bool CONFIG_FBCON_CFB8 m fi fi @@ -161,36 +175,44 @@ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ - "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" ]; then + "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ + "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_MATROX" = "y" ]; then define_bool CONFIG_FBCON_CFB16 y else if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ - "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" ]; then + "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ + "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_MATROX" = "m" ]; then define_bool CONFIG_FBCON_CFB16 m fi fi if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" ]; then + "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ + "$CONFIG_FB_MATROX" = "y" ]; then define_bool CONFIG_FBCON_CFB24 y else if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" ]; then + "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ + "$CONFIG_FB_MATROX" = "m" ]; then define_bool CONFIG_FBCON_CFB24 m fi fi if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ - "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" ]; then + "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_MATROX" = "y" ]; then define_bool CONFIG_FBCON_CFB32 y else if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ - "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" ]; then + "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_MATROX" = "m" ]; then define_bool CONFIG_FBCON_CFB32 m fi fi diff -u --recursive --new-file v2.1.128/linux/drivers/video/Makefile linux/drivers/video/Makefile --- v2.1.128/linux/drivers/video/Makefile Fri Oct 23 22:01:22 1998 +++ linux/drivers/video/Makefile Fri Nov 13 10:10:11 1998 @@ -123,6 +123,11 @@ endif endif +ifeq ($(CONFIG_FB_CVPPC),y) +L_OBJS += cvppcfb.o +CONFIG_FBGEN_BUILTIN = y +endif + ifeq ($(CONFIG_FB_MAC),y) L_OBJS += macfb.o endif @@ -308,6 +313,14 @@ else ifdef CONFIG_FBGEN_MODULE MX_OBJS += fbgen.o + endif +endif + +ifeq ($(CONFIG_FB_MATROX),y) +L_OBJS += matroxfb.o +else + ifeq ($(CONFIG_FB_MATROX),m) + M_OBJS += matroxfb.o endif endif diff -u --recursive --new-file v2.1.128/linux/drivers/video/amifb.c linux/drivers/video/amifb.c --- v2.1.128/linux/drivers/video/amifb.c Fri Oct 9 13:27:11 1998 +++ linux/drivers/video/amifb.c Fri Nov 13 10:10:11 1998 @@ -60,6 +60,7 @@ #include #include #include +#include #include